/* jesse at the bottom right of every page: his look, his waking, his corner and his question.
   Markup in each page, behaviour in main.js (drawing, waking) and jesse-corner.js (chat, question). */

@media (max-width: 760px) {
  /* phones: the footer clears jesse, not just the round button */
  .footer { padding-bottom: calc(146px + env(safe-area-inset-bottom)); }
}

/* ---------- jesse: the robot mark, drawn, woken and animated by main.js ---------- */
.agent { display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; }
.bot { position: relative; display: grid; place-items: center; width: 212px; padding: 0 0 20px; }
.bot-glow {
  position: absolute; inset: -18px; border-radius: 50%;
  background: radial-gradient(circle, color-mix(in srgb, var(--panel-hi) 90%, transparent) 30%, transparent 70%);
  opacity: 0; transition: opacity .6s, transform .6s var(--ease);
}
.bot-svg { position: relative; width: 150px; height: auto; overflow: visible; fill: none; stroke: var(--ink); stroke-width: .9; stroke-linecap: round; stroke-linejoin: round; }
.bot-head { transform-box: view-box; transform-origin: 12px 14px; }
.bot-eyes-shut { transition: opacity .25s; }
.bot-eyes-open ellipse { fill: var(--ink); stroke: none; transform-box: fill-box; transform-origin: center; transform: scaleY(0); transition: transform .3s var(--ease); }
.bot-dot { transition: fill .3s; }
.bot-talk { fill: var(--ink); stroke: none; opacity: 0; transform-box: fill-box; transform-origin: center; }
.bot-mouth { transition: opacity .2s; }

.agent:not([data-state="idle"]) .bot-eyes-shut { opacity: 0; }
.agent:not([data-state="idle"]) .bot-eyes-open ellipse { transform: scaleY(1); animation: bot-blink 4.2s 1s infinite; }
.agent:not([data-state="idle"]) .bot-dot { fill: var(--ink); }
.agent:not([data-state="idle"]) .bot-head { animation: none; }
.agent:not([data-state="idle"]) .bot-glow { opacity: 1; }
.agent[data-state="listening"] .bot-glow { animation: bot-glow 2.4s ease-in-out infinite; }
.agent[data-state="connecting"] .bot-dot { animation: bot-dot 1s ease-in-out infinite; }
.agent[data-state="speaking"] .bot-glow { animation: bot-glow .9s ease-in-out infinite; }
.agent[data-state="speaking"] .bot-mouth { opacity: 0; }
.agent[data-state="speaking"] .bot-talk { opacity: 1; animation: bot-talk .32s ease-in-out infinite alternate; }
@keyframes bot-blink { 0%, 94%, 100% { transform: scaleY(1); } 97% { transform: scaleY(.1); } }
@keyframes bot-glow { 50% { transform: scale(1.08); opacity: .6; } }
@keyframes bot-dot { 50% { opacity: .3; } }
@keyframes bot-talk { from { transform: scale(.9, .35); } to { transform: scale(1, 1); } }

/* he draws himself on arrival: about two seconds, one stroke after another */
.bot-svg .draw { stroke-dasharray: 1; stroke-dashoffset: 1; animation: bot-draw .5s cubic-bezier(.45, 0, .25, 1) both; }
.bot-svg .d-head  { animation-duration: .9s; animation-delay: .1s; }
.bot-svg .d-stem  { animation-duration: .25s; animation-delay: .9s; }
.bot-svg .d-dot   { animation-duration: .3s; animation-delay: 1.1s; }
.bot-svg .d-ears  { animation-duration: .35s; animation-delay: 1.15s; }
.bot-svg .d-eyes  { animation-duration: .4s; animation-delay: 1.45s; }
.bot-svg .d-mouth { animation-duration: .2s; animation-delay: 1.85s; }
/* hidden until its turn, so the round line ends never show as stray dots */
@keyframes bot-draw { 0% { stroke-dashoffset: 1; opacity: 0; } 2% { opacity: 1; } 100% { stroke-dashoffset: 0; opacity: 1; } }
/* with motion turned off, the finished robot is simply there */
@media (prefers-reduced-motion: reduce) { .bot-svg .draw { stroke-dashoffset: 0; } }

/* he wakes up: one sequence, driven by main.js.
   drawn asleep -> .is-waking: eyes half open, drowsy -> a slow blink ->
   .is-awake: eyes fully open, the smile comes, the antenna light fades in.
   Where he looks is eased in by the script, so nothing snaps. */
.bot-look { transform-box: view-box; transform-origin: 12px 13px; }
.bot-pupils { transform-box: view-box; }
/* one breathing rhythm from the first frame to the last, never restarted */
.bot-head { animation: bot-breathe 4.6s ease-in-out infinite; }
@keyframes bot-breathe { 0%, 100% { transform: translateY(0) scale(1); } 50% { transform: translateY(-.3px) scale(1.016); } }
.bot-eyes-shut { transition: opacity .3s ease; }
.bot-eyes-open ellipse { transition: transform .8s cubic-bezier(.25, .8, .3, 1); }
.agent.is-waking .bot-eyes-shut { opacity: 0; }
/* drowsy but content: soft, rounded half-open eyes, never a flat slit */
.agent.is-waking .bot-eyes-open ellipse { transform: scaleY(.62); transition-delay: .22s; }
.agent.is-awake .bot-eyes-open ellipse, .agent.is-blinking .bot-eyes-open ellipse { transition-delay: 0s; }
.agent.is-awake .bot-eyes-open ellipse { transform: scaleY(1); transition: transform .5s cubic-bezier(.3, 1.2, .5, 1); }
/* a blink: shut quickly, open a touch slower */
.agent.is-blinking .bot-eyes-open ellipse { transform: scaleY(.08); transition: transform .08s ease-in; }
.bot-mouth, .bot-smile { transition: opacity .8s ease; }
.bot-smile { opacity: 0; }
/* the smile arrives with the waking, so the drowsy moment already reads as content */
.agent.is-waking .bot-mouth { opacity: 0; }
.agent.is-waking .bot-smile { opacity: 1; }
/* antenna light: starts dark and fades into a slow pulse */
.agent.is-awake .bot-dot { animation: bot-led 3.2s ease-in-out .6s infinite both; }
@keyframes bot-led { 0%, 100% { fill: transparent; } 45%, 60% { fill: var(--ink); } }
@media (prefers-reduced-motion: reduce) {
  .agent.is-awake .bot-dot { animation: none; fill: var(--ink); }
}
/* once drawn, the lines are whole again: no dash seam where each stroke closes */
.agent.is-waking .bot-svg .draw, .agent.is-awake .bot-svg .draw { stroke-dasharray: none; }
button.bot { cursor: pointer; border-radius: 32px; -webkit-tap-highlight-color: transparent; }
button.bot:focus-visible { outline-offset: 4px; }

/* ---------- jesse at the bottom right: he lifts on hover and presses on click ---------- */
.jesse-corner {
  position: fixed; z-index: 91; right: 22px; bottom: 56px; padding: 0;
  display: grid; justify-items: end; gap: 8px; pointer-events: none;
}
/* he and the (unseen) chat button stand on the cookie notice while it is up: --jc-lift, set by jesse-corner.js */
.jesse-corner, .cb { transform: translateY(calc(-1 * var(--jc-lift, 0px))); transition: transform .6s var(--ease); }
html:has(dialog[open]) .jesse-corner { margin-right: var(--sbw, 0px); }
.jesse-corner > * { pointer-events: auto; }
.jesse-corner .bot {
  width: auto; padding: 6px; border-radius: 28px; cursor: pointer;
  transition: transform .5s var(--spring);
}
@media (hover: hover) { .jesse-corner .bot:hover { transform: translateY(-3px); } } /* a tap must not leave him lifted */
.jesse-corner .bot:active { transform: scale(.94); transition-duration: .12s; }
.jesse-corner .bot:focus-visible { outline-offset: 2px; }
.jesse-corner .bot-svg { width: 166px; }

/* his question, a speech bubble pointing down at him; it rises in once he is awake and stays */
.jc-hello {
  position: absolute; right: 8px; bottom: calc(100% + 8px); /* floats above him, so his corner never changes size */
  padding: 11px 17px; border-radius: 20px 20px 6px 20px;
  background: var(--panel-hi); color: var(--ink);
  font-size: 15px; font-weight: 500; letter-spacing: -.012em; white-space: nowrap; cursor: pointer;
  box-shadow: 0 0 0 1px var(--hair), var(--sh-3);
  transform-origin: 100% 100%; transition: box-shadow .3s var(--ease-out), transform .45s var(--spring);
}
@media (hover: hover) { .jc-hello:hover { box-shadow: 0 0 0 1px var(--hair-2), var(--sh-3); transform: translateY(-1px); } }
.jc-hello:active { transform: scale(.97); }
.jc-hello:not([hidden]) { animation: jc-up .7s var(--spring) backwards; }
.jc-hello[hidden] { display: none; }
.jc-hello.is-leaving { animation: jc-down .22s var(--ease-in) both; }
@keyframes jc-up { from { opacity: 0; transform: translateY(12px) scale(.9); } }
@keyframes jc-down { to { opacity: 0; transform: translateY(6px) scale(.96); } }

/* the old round chat button still does the work, unseen, sized like him so the chat window opens above him */
.cb { right: 22px; bottom: 56px; }
.cb-open { width: 180px; height: 143px; opacity: 0; pointer-events: none; }
.cb-panel { height: min(520px, calc(100svh - 324px - var(--jc-lift, 0px))); min-height: min(420px, calc(100svh - 236px - var(--jc-lift, 0px))); }

@media (max-width: 760px) {
  .jesse-corner, .cb { right: 12px; bottom: calc(22px + env(safe-area-inset-bottom)); }
  .jesse-corner .bot-svg { width: 110px; }
  .jc-hello { padding: 10px 15px; font-size: 14.5px; }
  .cb-open { width: 125px; height: 101px; }
  .cb-panel { height: min(70svh, 560px, calc(100svh - 151px - var(--jc-lift, 0px))); }
}
@media (max-width: 600px) {
  /* phones: his question sits beside him rather than above, so he takes less of the screen */
  .jc-hello { right: calc(100% + 4px); bottom: 20px; }
  .cb-panel { width: calc(100vw - 24px); }
  .cookie { right: 12px; } /* full width: jesse stands on it instead of beside it */
}
/* phones turned sideways: a smaller jesse, lower down */
@media (min-width: 761px) and (max-height: 560px) {
  .jesse-corner, .cb { bottom: 16px; }
  .jesse-corner .bot-svg { width: 96px; }
  .jc-hello { padding: 8px 13px; font-size: 13.5px; }
  .cb-open { width: 122px; height: 98px; }
  .cb-panel { height: calc(100svh - 138px - var(--jc-lift, 0px)); }
}

/* ---------- from page to page: once drawn, he stays ----------
   On every page but the home page, a jesse drawn earlier in the visit (.jesse-ready, set in <head>)
   starts already awake: no drawing, no waking, his question already up. The page transition keeps
   him in place (view-transition-name), so moving between pages never redraws him or flickers. */
.jesse-corner { view-transition-name: jesse; }
::view-transition-group(jesse) { animation: none; }
.theme-vt .jesse-corner { view-transition-name: none; }
.jesse-ready .jesse-corner .bot-svg .draw { animation: none; stroke-dashoffset: 0; stroke-dasharray: none; }
.jesse-ready .jesse-corner .bot-eyes-shut, .jesse-ready .jesse-corner .bot-mouth { opacity: 0; transition: none; }
.jesse-ready .jesse-corner .bot-smile { opacity: 1; transition: none; }
.jesse-ready .jesse-corner:not(.is-blinking) .bot-eyes-open ellipse { transform: scaleY(1); }
.jesse-ready .jesse-corner .bot-dot { fill: var(--ink); }
.jesse-ready .jesse-corner.is-awake .bot-dot { animation-delay: 0s; }
.jesse-ready .jc-hello:not([hidden]) { animation: none; }
