/* Cardo, the help bot, and its flight to a missed field. Loaded in the order web/index.html lists them; the order is the cascade. */
/* ---------- info bot (Cardo) ---------- */
#helpBot { position:fixed; right:22px; bottom:22px; z-index:65; width:62px; height:72px; border:none; background:transparent; padding:0; cursor:pointer; -webkit-tap-highlight-color:transparent; }
#helpBot .bot-svg { width:100%; height:100%; display:block; overflow:visible; filter:drop-shadow(0 10px 16px rgba(59,91,219,.35)); transition:filter var(--t-med); }
#helpBot:hover .bot-svg { filter:drop-shadow(0 14px 22px rgba(59,91,219,.5)); }
#helpBot:active { transform:translateY(1px); }
.bot-body { animation:botBob 3.2s ease-in-out infinite; transform-origin:50% 60%; transform-box:fill-box; }
@keyframes botBob { 0%,100%{ transform:translateY(0) rotate(0deg); } 50%{ transform:translateY(-3px) rotate(-1.5deg); } }
.bot-head { animation:botNod 3.2s ease-in-out infinite; transform-origin:50% 90%; transform-box:fill-box; }
@keyframes botNod { 0%,100%{ transform:rotate(0); } 50%{ transform:rotate(2.5deg); } }
.bot-eyes { animation:botBlink 4.6s infinite; transform-origin:center; transform-box:fill-box; }
@keyframes botBlink { 0%,93%,100%{ transform:scaleY(1); } 96%{ transform:scaleY(.14); } }
.bot-arm-r { animation:botWave 3.2s ease-in-out infinite; transform-origin:50% 0; transform-box:fill-box; }
@keyframes botWave { 0%,55%,100%{ transform:rotate(0); } 65%{ transform:rotate(-24deg); } 78%{ transform:rotate(8deg); } 88%{ transform:rotate(-12deg); } }
.bot-shadow { animation:botShadow 3.2s ease-in-out infinite; transform-origin:center; transform-box:fill-box; }
@keyframes botShadow { 0%,100%{ transform:scaleX(1); opacity:.18; } 50%{ transform:scaleX(.82); opacity:.11; } }
.bot-badge { position:absolute; top:-1px; right:-1px; width:20px; height:20px; border-radius:50%; background:var(--accent); color:#fff; font-size:12px; font-weight:700; display:grid; place-items:center; box-shadow:0 3px 8px rgba(59,91,219,.5); border:2px solid #fff; }
/* ---------- Cardo flies to a missed required field ---------- */
/* Fires ONLY on a blocked submit, never while typing: an analyst fills ~42 fields per case and a mascot
   that launches on every empty input would be intolerable by the third case. The flight is decoration on
   top of the real fix, which is still focus() + scrollIntoView() + the aria-live message. If the animation
   never runs (reduced motion, older engine, JS throw) the analyst is exactly where they were before. */
#helpBot.cardo-flying { z-index:80; cursor:default; }
/* Idle loops fight the pose, so they stop for the duration. The body keeps a forward tilt: a superman lean. */
#helpBot.cardo-flying .bot-body { animation:cardoLean 2.6s ease-in-out infinite alternate; }
@keyframes cardoLean { from{ transform:translateY(0) rotate(-7deg); } to{ transform:translateY(-4px) rotate(-11deg); } }
#helpBot.cardo-flying .bot-head { animation:none; transform:rotate(-4deg); }
/* Both arms swing out and hold, pointing at the field. -90deg = straight out to the RIGHT in SVG's
   y-down coordinate space (the arms hang downward at rest, so counter-clockwise a quarter turn is right).
   .cardo-left mirrors it for when the bot has to sit on the field's right-hand side. */
/* ONE hand points; the other rests. Two arms both aimed at the field needed the far one translated
   across the torso to stay visible, which read as a flailing double-point rather than an indication.
   A single extended arm with the other relaxed at the side is what a person actually does when pointing. */
#helpBot.cardo-flying .bot-arm-l, #helpBot.cardo-flying .bot-arm-r { animation:none; transition:transform .9s cubic-bezier(.25,1.2,.35,1); }
#helpBot.cardo-flying .bot-arm-r { transform:rotate(-84deg); }   /* near arm points right */
#helpBot.cardo-flying .bot-arm-l { transform:rotate(9deg); }     /* far arm rests at the side */
#helpBot.cardo-flying.cardo-left .bot-arm-l { transform:rotate(84deg); }   /* near arm points left */
#helpBot.cardo-flying.cardo-left .bot-arm-r { transform:rotate(-9deg); }   /* far arm rests */
/* Vertical pose, used when the field is too wide for the bot to stand beside it without covering it. */
#helpBot.cardo-flying.cardo-up .bot-arm-r { transform:rotate(174deg); }    /* one arm up at the field */
#helpBot.cardo-flying.cardo-up .bot-arm-l { transform:rotate(-9deg); }     /* far arm rests */
/* A visible leap between fields. scrollIntoView centres each target, so the bot ends up at roughly the
   same viewport spot every time and the page travels underneath it — correct, but it meant a hop showed
   no motion at all. This plays once on the way out so the move reads as the bot going somewhere. It
   overrides the idle lean for its duration and hands back automatically. */
#helpBot.cardo-hopping .bot-body { animation:cardoTravel .95s cubic-bezier(.3,.75,.3,1) 1 !important; }
@keyframes cardoTravel {
  0%   { transform:translateY(0) rotate(0deg) scale(1); }
  30%  { transform:translateY(-18px) rotate(-7deg) scale(1.04); }
  65%  { transform:translateY(-6px) rotate(3deg) scale(.99); }
  100% { transform:translateY(0) rotate(0deg) scale(1); }
}
#helpBot.cardo-flying.cardo-up .bot-body { animation:cardoHover 2.8s ease-in-out infinite alternate; }
@keyframes cardoHover { from{ transform:translateY(0) rotate(0deg); } to{ transform:translateY(-5px) rotate(0deg); } }
#helpBot.cardo-flying.cardo-left .bot-body { animation:cardoLeanL 2.6s ease-in-out infinite alternate; }
@keyframes cardoLeanL { from{ transform:translateY(0) rotate(7deg); } to{ transform:translateY(-4px) rotate(11deg); } }
#helpBot.cardo-flying .bot-badge { opacity:0; transition:opacity .4s; }
/* ---------- the happy reaction, once the field is filled ---------- */
/* Both arms go up in a cheer, overriding whichever pointing pose was active, and the body hops twice.
   Deliberately the ONLY fast motion in the whole sequence: the flight is a slow glide the analyst is meant
   to follow, the celebration is a quick beat that says "done" and releases them back to the form. */
#helpBot.cardo-flying.cardo-happy .bot-arm-l,
#helpBot.cardo-flying.cardo-happy .bot-arm-r { transform:rotate(175deg); transition:transform .3s cubic-bezier(.2,1.8,.4,1); }
#helpBot.cardo-flying.cardo-happy .bot-arm-l { transform:rotate(200deg); }
#helpBot.cardo-flying.cardo-happy .bot-arm-r { transform:rotate(160deg); }
#helpBot.cardo-flying.cardo-happy .bot-body { animation:cardoHop .42s ease-out 2; }
@keyframes cardoHop { 0%,100%{ transform:translateY(0) rotate(0deg); } 40%{ transform:translateY(-11px) rotate(0deg); } }
#helpBot.cardo-flying.cardo-happy .bot-head { animation:none; transform:rotate(0deg); }
/* Eyes squeeze into a smile. The eyes are a two-arc path, so flattening them vertically reads as closed-happy. */
#helpBot.cardo-flying.cardo-happy .bot-eyes { animation:none; transform:scaleY(.45) translateY(6px); transition:transform .25s; }
#cardoSay.happy { background:var(--ok,#0f6e56); }
#cardoSay.happy b { color:#c9f7e6; }
/* Speech bubble. Fixed-positioned by the JS beside the bot, never inside the scrolling form. */
#cardoSay { position:fixed; z-index:81; max-width:230px; background:var(--ink,#1a2234); color:#fff; font-size:12.5px;
  line-height:1.45; padding:9px 12px; border-radius:12px; box-shadow:0 10px 26px -8px rgba(20,30,60,.55);
  pointer-events:none; opacity:0; transform:translateY(6px) scale(.94); transition:opacity .45s, transform .45s cubic-bezier(.2,.9,.3,1.3), background .3s; }
#cardoSay.on { opacity:1; transform:none; }
/* Pointing at a field inside a dialog (z-index 10000): rise above its backdrop. Set by cardoPointAt. */
body.cardo-lift #helpBot.cardo-flying { z-index:10010; }
body.cardo-lift #cardoSay { z-index:10011; }
#cardoSay b { color:#9fd2ff; }
/* No tail. It was anchored to the bubble's bottom edge, which only made sense while the bubble was always
   directly above the bot; now that placement is chosen from four sides to dodge the form controls, a fixed
   tail points at empty space more often than at the bot. The bot's own outstretched arm is the pointer. */
/* The field itself is what the analyst has to act on, so it gets the loudest treatment, not the bot. */
.cardo-target { animation:cardoRing 1.15s ease-out 2; border-radius:var(--r-md,10px); }
@keyframes cardoRing {
  0%   { box-shadow:0 0 0 0 rgba(220,38,38,.45), 0 0 0 0 rgba(220,38,38,.22); }
  70%  { box-shadow:0 0 0 7px rgba(220,38,38,0),  0 0 0 14px rgba(220,38,38,0); }
  100% { box-shadow:0 0 0 0 rgba(220,38,38,0),    0 0 0 0 rgba(220,38,38,0); }
}
/* Reduced motion: no flight, no hovering mascot. The ring becomes a static outline that still says
   "this one". Honouring the preference by deleting the feature, not by speeding it up. */
@media (prefers-reduced-motion:reduce) {
  #helpBot.cardo-flying { display:none; }
  #cardoSay { transition:none; }
  .cardo-target { animation:none; outline:2px solid var(--bad,#dc2626); outline-offset:2px; }
}
#helpPanel { position:fixed; right:22px; bottom:104px; z-index:66; width:344px; max-width:calc(100vw - 44px); max-height:min(560px, calc(100vh - 140px)); overflow:auto;
  background:#fff; border:1px solid var(--line); border-radius:16px; box-shadow:var(--e-4); transform-origin:bottom right; animation:helpIn .22s cubic-bezier(.2,.8,.2,1); }
#helpPanel[hidden] { display:none; }
@keyframes helpIn { from{ opacity:0; transform:translateY(12px) scale(.97); } to{ opacity:1; transform:none; } }
.help-hd { display:flex; align-items:center; gap:9px; padding:13px 14px; border-bottom:1px solid var(--line-soft); position:sticky; top:0; background:#fff; }
.help-mini { font-size:18px; line-height:1; }
.help-hd b { flex:1; font-size:14px; color:var(--ink); }
.help-close { border:none; background:transparent; font-size:16px; color:var(--muted); cursor:pointer; width:28px; height:28px; border-radius:8px; }
.help-close:hover { background:var(--line-soft); color:var(--ink); }
.help-bd { padding:14px 16px 18px; font-size:13.5px; line-height:1.6; color:var(--muted); }
.help-bd h4 { margin:0 0 6px; font-size:14px; color:var(--ink); }
.help-bd p { margin:0 0 12px; }
.help-bd ol, .help-bd ul { margin:0 0 12px; padding-left:20px; }
.help-bd li { margin-bottom:6px; }
.help-bd b { color:var(--ink); }
.help-tip { background:var(--accent-soft); border:1px solid var(--accent-soft-2); border-radius:10px; padding:10px 12px; color:var(--ink); font-size:12.5px; }
.help-tip b { color:var(--accent); }
@media (max-width:560px){ #helpBot{ right:14px; bottom:14px; } #helpPanel{ right:14px; bottom:92px; } }
