/* ==========================================================================
   Nori · chatbot de la web pública de Norte
   Animaciones por frames con CSS puro (steps), sobre PNGs con transparencia.
   Todas las clases y animaciones llevan el prefijo «nori» para no chocar con el CSS del sitio.
   ========================================================================== */

/* Tamaño de Nori: lo comparten el widget y el espacio que se reserva al final de la página. */
html.has-nori, .nori { --n-size: clamp(104px, 11vw, 136px); }
/* Al llegar al final de la página Nori queda en un espacio reservado del pie y no tapa ningún enlace ni texto. */
html.has-nori .sf .sf__bar { padding-bottom: calc(var(--n-size) + 14px); }

.nori {
  --n-ink: #14122b;          /* línea del párpado (parte del dibujo de Nori) */
  --n-pur: #6d3bd2;          /* violeta de Norte */
  --n-pur-hi: #a98bf5;
  --n-bg: #0c0818;           /* tinta de Norte */
  --n-card: #150f26;
  --n-line: rgba(255, 255, 255, .14);
  --n-text: #ffffff;
  --n-mute: #c4bddb;

  position: fixed;
  right: max(12px, env(safe-area-inset-right, 0px));
  bottom: max(10px, env(safe-area-inset-bottom, 0px));
  z-index: 1000;
  /* El contenedor no captura clics: solo el cuerpo de Nori (.nori__hit) y el panel abierto. Así los enlaces y botones de la
     página siguen funcionando alrededor del personaje. */
  pointer-events: none;
  /* Mientras haces scroll Nori se aparta del borde (C4); la transición se anula con movimiento reducido. */
  transition: translate .25s ease;
  font-family: Inter, system-ui, -apple-system, 'Segoe UI', sans-serif;
  font-size: 14px;
  line-height: 1.45;
  color: var(--n-text);
}
.nori *, .nori *::before, .nori *::after { box-sizing: border-box; }
.nori[hidden] { display: none; }

.nori .nori-sr {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ---------- mascota (botón que abre el chat) ---------- */
.nori__mascot {
  pointer-events: none;      /* el clic lo recibe .nori__hit; el teclado sigue usando este botón */
  position: relative; display: block; width: var(--n-size); aspect-ratio: 1;
  padding: 0; margin: 0 0 0 auto; border: 0; background: none; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.nori__mascot:focus-visible { outline: 3px solid var(--n-pur-hi); outline-offset: 4px; border-radius: 20px; }
/* Área de clic: el rectángulo del cuerpo de Nori (medido sobre la parte opaca de las poses), con esquinas redondeadas. */
.nori__hit {
  position: absolute; top: 9%; right: 7%; bottom: 4%; left: 19%;
  border-radius: 22%; pointer-events: auto; cursor: pointer;
}
.nori__shadow {
  position: absolute; left: 18%; right: 18%; bottom: 1%; height: 7%;
  background: radial-gradient(ellipse at center, rgba(0, 0, 0, .38), transparent 70%);
}
.nori__stage { position: absolute; inset: 0; display: block; }
.nori__swap, .nori__poses { position: absolute; inset: 0; display: block; transform-origin: 50% 92%; }

/* "respiración": sube y baja por saltos */
.nori__poses { animation: nori-bob 3.2s steps(1, end) infinite; }
.nori__stage[data-pose="dormido"] .nori__poses { animation-duration: 5.6s; }
@keyframes nori-bob {
  0%, 49.9% { transform: translateY(0); }
  50%, 100% { transform: translateY(-1.6%); }
}

/* cambio de pose: rebote con sobreimpulso */
.nori__swap.is-swap { animation: nori-pop-pose .42s steps(1, end); }
@keyframes nori-pop-pose {
  0%   { transform: scale(.9, 1.06); }
  25%  { transform: scale(1.06, .94); }
  50%  { transform: scale(.98, 1.03); }
  75%  { transform: scale(1.02, .99); }
  100% { transform: scale(1); }
}

/* ---------- poses y frames ---------- */
.nori-pose { position: absolute; inset: 0; display: none; }
.nori-pose.is-on { display: block; }
.nori-pose img, .nori-pose .nori-fr { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.nori-pose img { user-select: none; -webkit-user-drag: none; pointer-events: none; }
.nori-pose .nori-fr2 { opacity: 0; }

/* dos frames que se alternan (cada uno con su propio keyframe) */
.nori-pose--hola.is-on .nori-fr1        { animation: nori-fr-a .9s  steps(1, end) infinite; }
.nori-pose--hola.is-on .nori-fr2        { animation: nori-fr-b .9s  steps(1, end) infinite; }
.nori-pose--escribiendo.is-on .nori-fr1 { animation: nori-fr-a .36s steps(1, end) infinite; }
.nori-pose--escribiendo.is-on .nori-fr2 { animation: nori-fr-b .36s steps(1, end) infinite; }
.nori-pose--hablando.is-on .nori-fr1    { animation: nori-fr-a .26s steps(1, end) infinite; }
.nori-pose--hablando.is-on .nori-fr2    { animation: nori-fr-b .26s steps(1, end) infinite; }
@keyframes nori-fr-a { 0%, 49.9% { opacity: 1; } 50%, 99.9% { opacity: 0; } 100% { opacity: 1; } }
@keyframes nori-fr-b { 0%, 49.9% { opacity: 0; } 50%, 99.9% { opacity: 1; } 100% { opacity: 0; } }

/* efectos sueltos (chispas, nube, zzz, signo de pregunta) */
.nori-pose .nori-fx { opacity: 0; animation: nori-fx-pop .5s steps(1, end) .15s forwards; }
.nori-pose--exito .nori-fx      { transform-origin: 50% 25%;  animation: nori-fx-pop .5s steps(1, end) .1s forwards,  nori-twinkle 1.3s steps(1, end) .7s infinite; }
.nori-pose--pensando .nori-fx   { transform-origin: 87% 16%;  animation: nori-fx-pop .5s steps(1, end) .2s forwards,  nori-float-small 2.4s steps(1, end) .8s infinite; }
.nori-pose--dormido .nori-fx    { transform-origin: 85% 18%;  animation: nori-fx-pop .5s steps(1, end) .2s forwards,  nori-zfloat 3s steps(1, end) .8s infinite; }
.nori-pose--confundido .nori-fx { transform-origin: 82% 22%;  animation: nori-fx-pop .5s steps(1, end) .25s forwards; }
@keyframes nori-fx-pop {
  0%   { opacity: 1; scale: .35; }
  22%  { opacity: 1; scale: 1.3; }
  46%  { opacity: 1; scale: .9; }
  70%  { opacity: 1; scale: 1.08; }
  100% { opacity: 1; scale: 1; }
}
@keyframes nori-twinkle   { 0%, 49.9% { opacity: 1; } 50%, 74.9% { opacity: .25; } 75%, 100% { opacity: 1; } }
@keyframes nori-float-small { 0%, 49.9% { translate: 0 0; } 50%, 100% { translate: 0 -2.5%; } }
@keyframes nori-zfloat {
  0%   { translate: 0 0;      opacity: 1; }
  25%  { translate: 1% -2%;   opacity: 1; }
  50%  { translate: 2% -4%;   opacity: 1; }
  75%  { translate: 3% -6%;   opacity: .35; }
  100% { translate: 0 0;      opacity: 1; }
}

/* "no entendí": sacudida de cabeza (una vez) */
.nori-pose--confundido.is-on { animation: nori-shake .55s steps(1, end) 1; transform-origin: 50% 92%; }
@keyframes nori-shake {
  0% { transform: rotate(-3deg); } 20% { transform: rotate(3deg); } 40% { transform: rotate(-2deg); }
  60% { transform: rotate(2deg); } 80% { transform: rotate(-1deg); } 100% { transform: rotate(0); }
}

/* ---------- parpadeo (párpados blancos + línea) ---------- */
.nori-eye { position: absolute; display: none; width: 9%; height: 10.8%; top: calc(40.5% + var(--ey, 0%)); pointer-events: none; }
.nori-eye--l { left: calc(35.5% + var(--ex, 0%)); }
.nori-eye--r { left: calc(55.5% + var(--ex, 0%)); }
.nori__stage[data-pose="pensando"]    { --ex: 1%; --ey: -1%; }
.nori__stage[data-pose="escribiendo"] { --ey: 1%; }
.nori__stage:is([data-pose="reposo"], [data-pose="hola"], [data-pose="seguridad"],
                [data-pose="pensando"], [data-pose="escribiendo"], [data-pose="hablando"]) .nori-eye { display: block; }
.nori-eye .nori-lid {
  position: absolute; left: 0; width: 100%; height: 0; background: #fff;
  animation: nori-blink 5.2s steps(1, end) infinite;
}
.nori-eye .nori-lid--t { top: 0; }
.nori-eye .nori-lid--b { bottom: 0; }
.nori-eye .nori-line {
  position: absolute; left: 4%; width: 92%; top: 50%; height: 8%; transform: translateY(-50%);
  background: var(--n-ink); border-radius: 2px; opacity: 0;
  animation: nori-blink-line 5.2s steps(1, end) infinite;
}
@keyframes nori-blink {
  0%, 82% { height: 0; } 83% { height: 25%; } 84%, 87% { height: 50%; } 88% { height: 25%; } 89%, 100% { height: 0; }
}
@keyframes nori-blink-line { 0%, 83.9% { opacity: 0; } 84%, 87.9% { opacity: 1; } 88%, 100% { opacity: 0; } }

/* ---------- entrada (patrón armed / play) ---------- */
.nori--armed .nori__mascot { opacity: 0; transform: translateY(35%) scale(.6); }
.nori--play .nori__mascot  { animation: nori-enter .65s steps(1, end) .25s forwards; }
@keyframes nori-enter {
  0%   { opacity: 1; transform: translateY(35%) scale(.6); }
  30%  { opacity: 1; transform: translateY(-9%) scale(1.08); }
  55%  { opacity: 1; transform: translateY(0) scale(.95); }
  80%  { opacity: 1; transform: translateY(0) scale(1.03); }
  100% { opacity: 1; transform: none; }
}

/* globito de saludo */
.nori__tip {
  position: absolute; right: 74%; top: 6%; width: max-content; max-width: min(240px, 58vw);
  padding: 8px 12px; border-radius: 14px 14px 3px 14px; background: #fff; color: var(--n-ink);
  font-weight: 600; box-shadow: 0 6px 18px rgba(0, 0, 0, .35);
  opacity: 0; pointer-events: none; transform-origin: 100% 100%;
}
.nori.is-tip .nori__tip { animation: nori-tip 6s steps(1, end) forwards; }
@keyframes nori-tip {
  0%   { opacity: 1; transform: scale(.4); }
  3%   { opacity: 1; transform: scale(1.12); }
  6%   { opacity: 1; transform: scale(.96); }
  9%, 92% { opacity: 1; transform: scale(1); }
  100% { opacity: 0; transform: scale(1); }
}

/* ---------- panel del chat ---------- */
.nori__panel {
  position: absolute; right: 0; bottom: calc(var(--n-size) + 8px);
  width: min(380px, calc(100vw - 24px));
  height: min(540px, calc(100dvh - var(--n-size) - 36px));
  display: flex; flex-direction: column;
  background: var(--n-bg); border: 1px solid var(--n-line); border-radius: 18px;
  box-shadow: 0 20px 56px rgba(0, 0, 0, .5); overflow: hidden; transform-origin: 100% 100%;
}
.nori__panel[hidden] { display: none; }
.nori__panel { pointer-events: auto; }
/* C4: durante el scroll Nori sale del borde derecho y no cubre nada; vuelve cuando el scroll se detiene. */
.nori.is-tucked { translate: calc(100% + 28px) 0; }
.nori__panel:not([hidden]) { animation: nori-panel-in .38s steps(1, end); }
@keyframes nori-panel-in {
  0%   { opacity: .4; transform: translateY(14px) scale(.93); }
  35%  { opacity: 1;  transform: translateY(-4px) scale(1.012); }
  65%  { transform: translateY(1px) scale(.996); }
  100% { transform: none; }
}
.nori__head {
  display: flex; align-items: center; gap: 10px; padding: 12px 14px;
  background: var(--n-card); border-bottom: 1px solid var(--n-line);
}
.nori__head-txt { flex: 1; min-width: 0; }
.nori__title { margin: 0; font-size: 15px; font-weight: 700; }
.nori__sub { margin: 0; font-size: 12px; color: var(--n-mute); }
.nori__close {
  width: 34px; height: 34px; border-radius: 50%; border: 1px solid var(--n-line);
  background: transparent; color: var(--n-text); font-size: 20px; line-height: 1; cursor: pointer;
}
.nori__close:hover { background: rgba(255, 255, 255, .08); }
.nori__new {
  flex: none; padding: 6px 12px; border-radius: 999px; border: 1px solid var(--n-line);
  background: transparent; color: var(--n-text); font: inherit; font-size: 12px; cursor: pointer; white-space: nowrap;
}
.nori__new:hover, .nori__new:focus-visible { background: rgba(255, 255, 255, .1); }
.nori__new:focus-visible { outline: 2px solid var(--n-pur-hi); outline-offset: 2px; }

.nori__log { flex: 1; overflow-y: auto; overscroll-behavior: contain; padding: 14px; display: flex; flex-direction: column; gap: 10px; }
.nori-msg { max-width: 86%; padding: 9px 12px; border-radius: 14px; overflow-wrap: anywhere; animation: nori-msg-in .24s steps(3, end); }
@keyframes nori-msg-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.nori-msg--bot  { align-self: flex-start; background: var(--n-card); border-bottom-left-radius: 4px; }
.nori-msg--user { align-self: flex-end; background: var(--n-pur); color: #fff; border-bottom-right-radius: 4px; }
.nori-msg--typing { display: flex; gap: 5px; align-items: center; padding: 13px 14px; }
.nori-msg--typing i { width: 7px; height: 7px; border-radius: 50%; background: var(--n-pur-hi); opacity: .35; animation: nori-dot 1s steps(1, end) infinite; animation-delay: calc(var(--i) * .22s); }
@keyframes nori-dot { 0% { opacity: .35; translate: 0 0; } 25% { opacity: 1; translate: 0 -3px; } 50%, 100% { opacity: .35; translate: 0 0; } }

/* Origen de la respuesta (predefinida o documentada) y reintento tras un error. */
.nori-kind { align-self: flex-start; margin: -5px 0 0 4px; font-size: 11.5px; color: var(--n-mute); }
.nori-chip--retry { border-color: var(--n-mute); color: var(--n-text); }
.nori__chips { display: flex; flex-wrap: wrap; gap: 6px; align-self: flex-start; max-width: 100%; }
.nori-chip {
  display: inline-block; padding: 6px 11px; border-radius: 999px; border: 1px solid var(--n-pur);
  background: transparent; color: var(--n-text); font: inherit; font-size: 13px; text-decoration: none; cursor: pointer;
}
.nori-chip:hover, .nori-chip:focus-visible { background: var(--n-pur); }
.nori-chip--link { border-color: var(--n-pur-hi); color: var(--n-pur-hi); }
.nori-chip--link:hover, .nori-chip--link:focus-visible { color: #fff; }

.nori__form { display: flex; gap: 8px; padding: 10px 12px; border-top: 1px solid var(--n-line); background: var(--n-bg); }
.nori__input {
  flex: 1; min-width: 0; padding: 10px 12px; border-radius: 12px; border: 1px solid var(--n-line);
  background: var(--n-card); color: var(--n-text); font: inherit; font-size: 16px;
}
.nori__input::placeholder { color: var(--n-mute); }
.nori__input:focus-visible, .nori-chip:focus-visible, .nori__close:focus-visible, .nori__send:focus-visible { outline: 2px solid var(--n-pur-hi); outline-offset: 2px; }
.nori__send {
  padding: 0 16px; border-radius: 12px; border: 0; background: var(--n-pur); color: #fff;
  font: inherit; font-weight: 600; cursor: pointer;
}
.nori__send:disabled { opacity: .5; cursor: not-allowed; }
.nori__legal { margin: 0; padding: 0 14px 10px; font-size: 11.5px; color: var(--n-mute); background: var(--n-bg); }

/* ---------- móvil ---------- */
@media (max-width: 520px) {
  html.has-nori, .nori { --n-size: 96px; }
  .nori__panel { width: calc(100vw - 20px); right: 0; }
  .nori__tip { right: 70%; }
}

/* ---------- movimiento reducido: estado final, sin bucles ---------- */
@media (prefers-reduced-motion: reduce) {
  .nori *, .nori *::before, .nori *::after { animation: none !important; }
  .nori { transition: none; }
  .nori--armed .nori__mascot { opacity: 1; transform: none; }
  .nori-pose .nori-fx { opacity: 1; }
  .nori-pose .nori-fr2 { opacity: 0 !important; }
  .nori.is-tip .nori__tip { opacity: 1; }
}
