/* Djaal chat mascot – transparent OBS browser-source overlay (designed for 400x700) */
:root { --pink: #ff3fa4; --pink-deep: #d81b7a; --ink: #0d0a0c; --scale: 1; }
html, body { margin: 0; padding: 0; background: transparent !important; overflow: hidden; }
body { width: 100vw; height: 100vh; font-family: "Arial Black", "Segoe UI Black", "Helvetica Neue", Arial, sans-serif; }
#stage { position: absolute; inset: 0; pointer-events: none; z-index: 2; }
#bubble-wrap { z-index: 3; }
#mascot { position: absolute; left: 50%; bottom: 0; transform: translateX(-50%);
          height: calc(600px * var(--scale)); aspect-ratio: 274 / 540; }
#mascot video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain;
                opacity: 0; transition: opacity 160ms linear; background: transparent; }
#mascot video.on { opacity: 1; }

/* comic speech bubble, anchored just above the horns (JS sets --head-y) */
#bubble-wrap { position: absolute; left: 0; right: 0; bottom: calc(100% - var(--head-y, 180px));
               display: flex; justify-content: center; padding: 0 10px; box-sizing: border-box; }
.bubble { position: relative; max-width: calc(370px * var(--scale)); box-sizing: border-box;
          background: #fff; color: var(--ink); border: calc(4px * var(--scale)) solid var(--ink);
          border-radius: calc(22px * var(--scale)); padding: calc(10px * var(--scale)) calc(16px * var(--scale));
          font-size: calc(20px * var(--scale)); line-height: 1.22; font-weight: 900; letter-spacing: .2px;
          box-shadow: calc(5px * var(--scale)) calc(5px * var(--scale)) 0 var(--pink-deep);
          word-wrap: break-word; overflow-wrap: anywhere;
          transform-origin: 50% 100%; transform: scale(.2) translateY(20px); opacity: 0;
          transition: transform 220ms cubic-bezier(.2,1.6,.4,1), opacity 160ms ease-out; }
.bubble.show { transform: scale(1) translateY(0); opacity: 1; }
.bubble::after, .bubble::before { content: ""; position: absolute; left: 50%; border-style: solid; }
.bubble::before { /* tail outline */ bottom: calc(-22px * var(--scale)); margin-left: calc(-14px * var(--scale));
  border-width: calc(22px * var(--scale)) calc(14px * var(--scale)) 0 calc(14px * var(--scale));
  border-color: var(--ink) transparent transparent transparent; }
.bubble::after { /* tail fill */ bottom: calc(-14px * var(--scale)); margin-left: calc(-9px * var(--scale));
  border-width: calc(15px * var(--scale)) calc(9px * var(--scale)) 0 calc(9px * var(--scale));
  border-color: #fff transparent transparent transparent; }
.bubble .who { color: var(--pink-deep); margin-right: .35em; -webkit-text-stroke: 0; }
.bubble .who:empty { display: none; }
/* hype / event bubble */
.bubble.hype { background: var(--pink); color: #fff; box-shadow: calc(5px * var(--scale)) calc(5px * var(--scale)) 0 var(--ink);
               text-shadow: 2px 2px 0 var(--ink), -1px -1px 0 var(--ink), 1px -1px 0 var(--ink), -1px 1px 0 var(--ink);
               font-size: calc(23px * var(--scale)); }
.bubble.hype::after { border-top-color: var(--pink); }
.bubble.hype .who { color: #fff; }
.bubble.help { font-size: calc(17px * var(--scale)); }

#status { position: fixed; right: 6px; top: 6px; width: 9px; height: 9px; border-radius: 50%; background: #666; display: none; }
body.debug #status, body.test #status { display: block; }
#status.ok { background: #3ddc84; } #status.wait { background: #ffb020; } #status.err { background: #ff3355; }

#testpanel { position: fixed; left: 6px; bottom: 6px; z-index: 1; opacity: .85; font: 11px/1.35 ui-monospace, Menlo, Consolas, monospace; color: #fff;
             background: rgba(0,0,0,.55); padding: 6px 8px; border-radius: 6px; white-space: pre; pointer-events: none; }

/* layered rig: body video + head image, 274x540 clip space scaled by JS */
#mascot { aspect-ratio: auto; }
#rig { position: absolute; left: 0; top: 0; width: 274px; height: 540px; transform-origin: 0 0; }
#rig video { position: absolute; left: 0; top: 0; width: 274px; height: 540px; }
#head { position: absolute; left: 0; top: 0; transform-origin: 0 0; will-change: transform; }
#head img { position: absolute; left: 0; top: 0; width: 100%; height: 100%; visibility: hidden; }
#head img.on { visibility: visible; }
#head.hidden { display: none; }
/* test-mode mic meter */
#meter { position: relative; margin-top: 5px; width: 220px; height: 10px; background: rgba(255,255,255,.15); border-radius: 3px; overflow: hidden; }
#meterfill { position: absolute; left: 0; top: 0; bottom: 0; width: 0; background: linear-gradient(90deg, #3ddc84, #ffb020 60%, #ff3fa4); }
#meterhalf, #meteropen { position: absolute; top: -2px; bottom: -2px; width: 2px; background: #fff; }
#meteropen { background: #ff3fa4; }

/* ---- Djaal interactivity ---- */
#fx { position: absolute; left: 0; top: 0; pointer-events: none; z-index: 2; }
#mascot { z-index: 1; }
#fxw { position: absolute; inset: 0; transform-origin: 50% 100%; }
#fxw.hug   { animation: dj-hug 2.3s ease-in-out both; }
#fxw.lurk  { animation: dj-lurk 3.4s ease-in-out both; }
#fxw.shake { animation: dj-shake .55s ease-in-out 3; }
#fxw.pop   { animation: dj-pop .6s cubic-bezier(.2,1.8,.4,1) both; }
#fxw.sad   { animation: dj-sad 1.4s ease-in-out both; }
@keyframes dj-hug { 0% { transform: none; } 12% { transform: scale(1.12, .9); } 24% { transform: scale(.95, 1.06) rotate(-3deg); }
  38% { transform: scale(1.14, .88) rotate(2deg); } 52% { transform: scale(.96, 1.05); } 66% { transform: scale(1.12, .9) rotate(-2deg); } 82% { transform: scale(.98, 1.03); } 100% { transform: none; } }
@keyframes dj-lurk { 0% { transform: none; opacity: 1; } 35% { transform: translateY(105%) scale(.9); opacity: .15; }
  70% { transform: translateY(105%) scale(.9); opacity: 0; } 100% { transform: none; opacity: 1; } }
@keyframes dj-shake { 0%,100% { transform: rotate(0); } 25% { transform: rotate(-5deg) translateX(-4px); } 75% { transform: rotate(5deg) translateX(4px); } }
@keyframes dj-pop { 0% { transform: scale(1); } 40% { transform: scale(1.12, .92); } 100% { transform: scale(1); } }
@keyframes dj-sad { 0% { transform: none; } 30%,70% { transform: translateY(4%) scale(1.03, .95) rotate(-4deg); } 100% { transform: none; } }

/* Djaal's own lines: no "name:" label, pink outline, his name as a little tag */
.bubble.djaal { border-color: var(--pink-deep); }
.bubble.djaal::before { border-top-color: var(--pink-deep); }
.bubble.djaal .msg::before { content: "DJAAL"; display: block; font-size: .55em; letter-spacing: 1.5px; color: var(--pink-deep); margin-bottom: 1px; }
.bubble.djaal.hype .msg::before, .bubble.djaal.build .msg::before { color: #fff; opacity: .9; }
.bubble.build { background: linear-gradient(135deg, #2a0b12, #6d1420 60%, #c2361b); color: #ffe9c7; border-color: var(--ink);
                box-shadow: calc(5px * var(--scale)) calc(5px * var(--scale)) 0 #ff8a1f; text-shadow: 1px 1px 0 #000; }
.bubble.build::after { border-top-color: #6d1420; } .bubble.build::before { border-top-color: var(--ink); }
.bubble.love { background: #ffe3f1; } .bubble.love::after { border-top-color: #ffe3f1; }
.bubble.roll .msg { font-variant-numeric: tabular-nums; }
.bubble.roll.landed { animation: dj-land .35s cubic-bezier(.2,1.8,.4,1); }
@keyframes dj-land { 0% { transform: scale(1); } 50% { transform: scale(1.12); } 100% { transform: scale(1); } }
.bubble[class~="8ball"] { background: #15121a; color: #f3eaff; border-color: #b44bff; box-shadow: calc(5px * var(--scale)) calc(5px * var(--scale)) 0 #b44bff; }
.bubble[class~="8ball"]::after { border-top-color: #15121a; } .bubble[class~="8ball"]::before { border-top-color: #b44bff; }
.bubble[class~="8ball"] .msg::before { color: #d8a6ff; }
.bubble.greet { background: #fff7c2; } .bubble.greet::after { border-top-color: #fff7c2; }
/* demo background (test.html?demobg=1) so transparency/effects are visible in recordings */
html.demobg body { background: radial-gradient(circle at 30% 20%, #3b2a4a, #120d18 70%) !important; }

/* ---- Joll Chat Mascot 2.0 (CONFIG.mascot = 'joll'): whole-stage rig, bottom-centred, poses swapped with a snap-pop ---- */
#mascot.joll { left: 0; right: 0; top: 0; bottom: 0; width: auto; height: auto; transform: none; aspect-ratio: auto; }
#jrig { position: absolute; inset: 0; }
#jsway { position: absolute; left: 50%; bottom: 0; width: 0; height: 0; transform-origin: 50% 100%; animation: jsway 11s ease-in-out infinite; }
#jpop { position: absolute; left: 0; bottom: 0; width: 0; height: 0; transform-origin: 0 0; will-change: transform; }
#jbob { position: absolute; left: 0; bottom: 0; width: 0; height: 0; transform-origin: 0 0; animation: jbob-idle 3s ease-in-out infinite; }
#jrig.react #jbob { animation: jbob-react .9s ease-in-out infinite; }
#jrig.react #jsway { animation: none; }
.jimg { position: absolute; max-width: none; visibility: hidden; user-select: none; }
.jimg.on { visibility: visible; }
.jimg.cut { -webkit-mask-image: linear-gradient(to top, transparent 0, #000 34px); mask-image: linear-gradient(to top, transparent 0, #000 34px); }
#jshadow { position: absolute; left: 50%; bottom: 6px; height: 18px; width: 180px; transform: translateX(-50%); border-radius: 50%;
           background: radial-gradient(closest-side, rgba(20,0,25,.38), rgba(20,0,25,0)); animation: jshadow 3s ease-in-out infinite; transition: opacity .12s; }
#jrig.react #jshadow { animation-duration: .9s; }
#jink { position: absolute; pointer-events: none; opacity: 0; overflow: visible; }
/* idle: slow breathing bob (feet stay near the floor) + a rare tiny sway */
@keyframes jbob-idle { 0%, 100% { transform: translateY(0) scale(1, 1); } 50% { transform: translateY(-5px) scale(.996, 1.012); } }
@keyframes jbob-react { 0%, 100% { transform: translateY(0) scale(1.01, .985); } 50% { transform: translateY(-10px) scale(.99, 1.02); } }
@keyframes jshadow { 0%, 100% { transform: translateX(-50%) scale(1); } 50% { transform: translateX(-50%) scale(.92); } }
@keyframes jsway { 0%, 62%, 100% { transform: rotate(0); } 70% { transform: rotate(1.3deg); } 80% { transform: rotate(-1deg); } 88% { transform: rotate(.4deg); } }

/* ---- Joll roaming (CONFIG.joll.roam): JS moves #jsway (left/bottom); walk / run cycles on #jbob; #jface mirrors for left ---- */
#jshadow { left: 50%; }
#jface { position: absolute; left: 0; bottom: 0; width: 0; height: 0; transform-origin: 0 0; }
#jrig.walk #jsway, #jrig.run #jsway { animation: none; }
#jrig.walk #jbob { animation: jwalk .56s ease-in-out infinite; }
#jrig.run  #jbob { animation: jrun .3s ease-in-out infinite; }
#jrig.walk #jshadow { animation-duration: .28s; }
#jrig.run  #jshadow { animation-duration: .15s; }
/* step bob + squash on each footfall + alternating tilt (pivot at the feet) */
@keyframes jwalk {
  0%, 100% { transform: translateY(0) rotate(-2.5deg) scale(1.03, .96); }
  25%      { transform: translateY(-9px) rotate(0deg) scale(.98, 1.03); }
  50%      { transform: translateY(0) rotate(2.5deg) scale(1.03, .96); }
  75%      { transform: translateY(-9px) rotate(0deg) scale(.98, 1.03); } }
@keyframes jrun {
  0%, 100% { transform: translateY(0) rotate(-4deg) scale(1.05, .93); }
  25%      { transform: translateY(-16px) rotate(1deg) scale(.96, 1.05); }
  50%      { transform: translateY(0) rotate(4deg) scale(1.05, .93); }
  75%      { transform: translateY(-16px) rotate(-1deg) scale(.96, 1.05); } }
/* speed lines trail behind him while running (inside #jface, so they flip with him) */
#jspeed { position: absolute; left: 0; bottom: 60px; width: 0; height: 0; display: none; }
#jrig.run #jspeed { display: block; }
#jspeed i { position: absolute; right: 0; height: 5px; border-radius: 3px; background: #0d0a0c; animation: jspeed .24s linear infinite; }
#jspeed i:nth-child(1) { bottom: 150px; width: 70px; right: 140px; }
#jspeed i:nth-child(2) { bottom: 110px; width: 110px; right: 150px; animation-delay: -.08s; }
#jspeed i:nth-child(3) { bottom: 70px; width: 85px; right: 145px; animation-delay: -.16s; }
#jspeed i:nth-child(4) { bottom: 30px; width: 60px; right: 150px; animation-delay: -.04s; }
@keyframes jspeed { 0% { transform: translateX(20px); opacity: 0; } 30% { opacity: 1; } 100% { transform: translateX(-30px); opacity: 0; } }
/* bubble tail follows him when the bubble is clamped at a screen edge */
.bubble::before { left: calc(50% + var(--tail, 0px)); }
.bubble::after  { left: calc(50% + var(--tail, 0px)); }
#bubble-wrap { will-change: transform; }
/* keep the bubble (incl. its pop-in overshoot) inside narrow sources */
.bubble { max-width: min(calc(370px * var(--scale)), calc(100vw - 44px)); }

/* ---- web copy (djaaltard-site): Djaal roams inside his own strip iframe on a dark page ---- */
html, body { background: transparent !important; }
#stage { pointer-events: none; }
.jimg.on { pointer-events: auto; cursor: pointer; -webkit-user-drag: none; -webkit-tap-highlight-color: transparent; touch-action: manipulation; }
#jspeed { bottom: 22px; transform: scale(.4); }
#jspeed i { background: #f3dfb8; }
#jshadow { background: radial-gradient(closest-side, rgba(0,0,0,.65), rgba(0,0,0,0)); }
#status { display: none !important; }
