/* ============================================================
   MONDUL — the guide
   ------------------------------------------------------------
   A small robot in the bottom-right corner who reacts to the
   pointer, leans when you scroll, and says something useful about
   whatever section you are looking at.

   HE REPLACED TWO OTHER FLOATING THINGS RATHER THAN JOINING THEM.
   There was already an Ask MONDUL button bottom-left and a reading
   ring bottom-right. A third floating widget would have made three
   things competing for the same corners on a platform whose whole
   argument is that it does not waste your attention. So: Mondul IS
   the Ask launcher — clicking him opens the answer engine — the
   reading ring sits directly above him as a small halo, and the
   old button is retired. One character, three jobs.

   Structural rule observed throughout, the same one that governs
   the hero: a group that carries a CSS transform never also
   carries an SVG transform attribute. Position is baked into the
   path coordinates; every animated <g> is transform-free in the
   markup and gets `transform-box: fill-box` with an explicit
   origin here.
   ============================================================ */

#mondul{
  position:fixed; right:30px; bottom:30px; z-index:9999;
  display:flex; align-items:flex-end; gap:12px;
  pointer-events:none;               /* only the parts that need it */
}
#mondul *{pointer-events:auto}

/* ---------- the speech bubble ---------- */
.mdBubble{
  max-width:250px; padding:13px 16px; border-radius:16px 16px 4px 16px;
  font-size:.83rem; line-height:1.6; color:var(--forest);
  background:rgba(255,253,248,.72);
  border:1px solid rgba(255,255,255,.6);
  box-shadow:0 18px 44px -22px rgba(15,46,36,.5), 0 1px 0 rgba(255,255,255,.7) inset;
  backdrop-filter:blur(16px) saturate(1.25);
  -webkit-backdrop-filter:blur(16px) saturate(1.25);
  opacity:0; transform:translate3d(14px,8px,0) scale(.9); transform-origin:100% 100%;
  transition:opacity .3s var(--e-swift,ease), transform .46s var(--e-spring,ease);
  pointer-events:none;
}
#mondul.talk .mdBubble{opacity:1; transform:none}
body.km .mdBubble{line-height:1.95}
body.zh .mdBubble{line-height:1.85}
.mdBubble b{display:block;font-size:.68rem;letter-spacing:.13em;text-transform:uppercase;
 color:var(--emerald);font-weight:700;margin-bottom:4px}
body.km .mdBubble b,body.zh .mdBubble b{text-transform:none;letter-spacing:.02em}

/* ---------- the robot ---------- */
.mdBot{
  width:72px; height:96px; border:0; background:none; padding:0; cursor:pointer;
  -webkit-tap-highlight-color:transparent;
  transition:transform .5s var(--e-out,ease);
}
.mdBot:hover{transform:translateY(-4px) scale(1.04)}
.mdBot:active{transform:translateY(-1px) scale(.97);transition-duration:.1s}
.mdBot svg{display:block;width:72px;height:96px;overflow:visible}

/* Layer 1 — he hovers. Never touches the ground. */
.mdFloat{transform-box:fill-box;transform-origin:50% 100%;
 animation:mdFloat 3.6s ease-in-out infinite}
@keyframes mdFloat{
 0%,100%{transform:translateY(0)}
 50%    {transform:translateY(-5px)}
}

/* Layer 2 — the scroll lean. --lean is written by mondul.js from
   scroll velocity; the settle back to 0 is the whole point of the
   curve, so it gets the long one. */
.mdLean{--lean:0deg;
 transform-box:fill-box; transform-origin:50% 92%;
 transform:rotate(var(--lean));
 transition:transform .85s cubic-bezier(.25,1,.5,1)}

/* Layer 3 — the head. A slow idle tilt, plus --look from the
   pointer. Two different sources on one property would fight, so
   the idle tilt lives on an outer group and the look on an inner. */
.mdHeadIdle{transform-box:fill-box;transform-origin:50% 100%;
 animation:mdTilt 9s ease-in-out infinite}
@keyframes mdTilt{
 0%,32%,100%{transform:rotate(0deg)}
 42%       {transform:rotate(-5.5deg)}
 58%       {transform:rotate(0deg)}
 70%       {transform:rotate(4.5deg)}
 82%       {transform:rotate(0deg)}
}
.mdHeadLook{--hx:0px; --hy:0px; --hr:0deg;
 transform-box:fill-box; transform-origin:50% 100%;
 transform:translate(var(--hx),var(--hy)) rotate(var(--hr));
 transition:transform .55s cubic-bezier(.25,1,.5,1)}

/* the eyes track, and blink */
.mdEyes{--ex:0px; --ey:0px;
 transform:translate3d(var(--ex),var(--ey),0);
 transition:transform .35s cubic-bezier(.25,1,.5,1)}
.mdEye{transform-box:fill-box;transform-origin:50% 50%}
#mondul.blink .mdEye{transform:scaleY(.12)}
.mdEye{transition:transform .09s var(--e-swift,ease)}

/* glowing parts breathe */
.mdGlow{animation:mdPulse 2.9s ease-in-out infinite}
@keyframes mdPulse{0%,100%{opacity:.55}50%{opacity:1}}
.mdAnt{animation:mdPulse 1.7s ease-in-out infinite}

/* a soft ground shadow that reacts to the float */
.mdShadow{animation:mdShadow 3.6s ease-in-out infinite}
@keyframes mdShadow{
 0%,100%{opacity:.30;transform:scaleX(1)}
 50%    {opacity:.18;transform:scaleX(.84)}
}
.mdShadow{transform-box:fill-box;transform-origin:50% 50%}

/* thinking state, while the answer engine is open */
#mondul.busy .mdAnt{animation-duration:.5s}

/* The old launcher is retired — Mondul does that job now. Kept in
   the DOM because ask.js owns it and clicking Mondul clicks it. */
.askfab{display:none!important}

/* Back-to-top stacks above the reading halo, which is above him. */
#top{bottom:176px;right:34px}

@media(max-width:760px){
  #mondul{right:16px;bottom:16px}
  .mdBot,.mdBot svg{width:56px;height:74px}
  .mdBubble{max-width:180px;font-size:.78rem;padding:10px 13px}
  #top{bottom:104px;right:20px}
}

@media(prefers-reduced-motion:reduce){
  .mdFloat,.mdHeadIdle,.mdGlow,.mdAnt,.mdShadow{animation:none!important}
  .mdLean,.mdHeadLook,.mdEyes,.mdBot{transition:none!important;transform:none!important}
  .mdBubble{transition:opacity .2s linear}
}

@media print{ #mondul{display:none} }

/* ============================================================
   THE DETAIL PANEL
   Anchored to Mondul, so it travels with him when he is dragged.
   ============================================================ */
#mondul{position:fixed}
.mdPanel{
  position:absolute; right:0; bottom:100%; margin-bottom:14px;
  width:min(360px, calc(100vw - 40px));
  max-height:min(62vh, 560px); overflow-y:auto;
  background:rgba(255,253,248,.86);
  border:1px solid rgba(255,255,255,.6); border-radius:18px;
  box-shadow:0 30px 70px -28px rgba(15,46,36,.6), 0 1px 0 rgba(255,255,255,.75) inset;
  backdrop-filter:blur(20px) saturate(1.3);
  -webkit-backdrop-filter:blur(20px) saturate(1.3);
  opacity:0; visibility:hidden;
  transform:translate3d(0,14px,0) scale(.94); transform-origin:100% 100%;
  transition:opacity .28s var(--e-swift,ease),
             transform .52s var(--e-spring,ease),
             visibility .28s;
  overscroll-behavior:contain;
}
/* NOT `.panel`. That class already exists site-wide for the tab
   panels and carries `display:none`, so putting it on #mondul would
   have made him vanish the instant his own panel opened. Every
   state class here is prefixed for that reason. */
#mondul.mdopen .mdPanel{opacity:1; visibility:visible; transform:none}

.mdpHead{display:flex;align-items:center;gap:10px;padding:16px 18px 10px;
 position:sticky;top:0;background:linear-gradient(rgba(255,253,248,.95),rgba(255,253,248,.62));
 backdrop-filter:blur(8px);z-index:2}
.mdpHead h3{font-family:'Fraunces',Georgia,serif;font-size:1.02rem;color:var(--forest);
 margin:0;flex:1;font-weight:600}
.mdpX{width:28px;height:28px;border-radius:9px;border:1px solid var(--line);
 background:rgba(255,255,255,.7);color:var(--forest);font-size:1.1rem;line-height:1;
 cursor:pointer;transition:background .2s var(--e-swift,ease),transform .3s var(--e-out,ease)}
.mdpX:hover{background:var(--sand);transform:rotate(90deg)}

.mdpBody{padding:0 18px 4px}
.mdpLead{font-size:.9rem;line-height:1.7;color:var(--forest);margin:0 0 14px;font-weight:500}
body.km .mdpLead{line-height:2}
.mdpFact{border-top:1px solid var(--line);padding:12px 0 4px;
 opacity:0;transform:translate3d(0,10px,0);
 animation:mdpIn .5s var(--e-out,ease) forwards}
.mdpFact:nth-child(2){animation-delay:.05s}
.mdpFact:nth-child(3){animation-delay:.10s}
.mdpFact:nth-child(4){animation-delay:.15s}
.mdpFact:nth-child(5){animation-delay:.20s}
.mdpFact:nth-child(6){animation-delay:.25s}
@keyframes mdpIn{to{opacity:1;transform:none}}
.mdpFact h4{font-size:.84rem;color:var(--forest);margin:0 0 5px;font-weight:600}
.mdpFact p{font-size:.82rem;line-height:1.65;color:var(--muted);margin:0 0 6px}
.mdpSrc{display:block;font-size:.68rem;color:var(--emerald);line-height:1.5}
.mdpNone{font-size:.84rem;color:var(--muted);margin:0 0 8px}
.mdpNote{font-size:.75rem;color:var(--rust);margin:0 18px 4px;line-height:1.55}

.mdpFoot{display:flex;gap:8px;flex-wrap:wrap;padding:12px 18px 16px;
 position:sticky;bottom:0;background:linear-gradient(rgba(255,253,248,.62),rgba(255,253,248,.95));
 backdrop-filter:blur(8px)}
.mdpBtn{border:1px solid var(--line);background:rgba(255,255,255,.75);border-radius:22px;
 padding:8px 15px;font:inherit;font-size:.78rem;font-weight:600;color:var(--forest);cursor:pointer;
 transition:background .22s var(--e-swift,ease),border-color .22s var(--e-swift,ease),
            transform .34s var(--e-out,ease)}
.mdpBtn:hover{background:var(--mint);border-color:var(--emerald);transform:translateY(-2px)}
.mdpBtn:active{transform:scale(.96);transition-duration:.09s}
.mdpSpeak{background:var(--forest);color:#fff;border-color:var(--forest)}
.mdpSpeak:hover{background:var(--emerald);border-color:var(--emerald)}

/* ---------- drag ---------- */
.mdBot{cursor:grab; touch-action:none}
#mondul.dragging .mdBot{cursor:grabbing}
#mondul.dragging .mdBubble,#mondul.dragging .mdPanel{opacity:0;visibility:hidden}
#mondul.dragging .mdFloat{animation-play-state:paused}

/* ---------- speaking ---------- */
#mondul.speaking .mdAnt{animation-duration:.42s}
#mondul.speaking .mdEye{fill:#9BF0C8}
#mondul.speaking .mdGlow{animation-duration:.7s}

@media(max-width:760px){
  .mdPanel{position:fixed;right:12px;left:12px;bottom:96px;width:auto;max-height:58vh}
}
@media(prefers-reduced-motion:reduce){
  .mdPanel{transition:opacity .18s linear,visibility .18s}
  .mdpFact{opacity:1!important;transform:none!important;animation:none!important}
  .mdpX:hover,.mdpBtn:hover{transform:none}
}

/* ============================================================
   CARRYING HIM SOMEWHERE
   ============================================================ */
/* One frame of transparency, so the hit test can see through him
   to whatever he is hovering over. Without this, dropping him
   always finds Mondul. */
#mondul.mdGhost,#mondul.mdGhost *{pointer-events:none!important}

/* what he is about to land on */
.mdTarget{
  outline:2px solid var(--emerald);
  outline-offset:4px;
  border-radius:8px;
  background:rgba(31,122,90,.06);
  transition:outline-color .2s var(--e-swift,ease),background .2s var(--e-swift,ease);
}
#mondul.carrying .mdBot{transform:rotate(-7deg) scale(1.06)}
#mondul.carrying .mdArmL{transform:rotate(-22deg)}
#mondul.carrying .mdArmR{transform:rotate(22deg)}
.mdArmL,.mdArmR{transform-box:fill-box;transform-origin:50% 12%;
 transition:transform .45s var(--e-spring,ease)}

/* the leaf on his sash turns slowly — a small sign of life on the
   part of him that says what he is here for */
.mdLeaf{transform-box:fill-box;transform-origin:50% 50%;
 animation:mdLeaf 7s ease-in-out infinite}
@keyframes mdLeaf{0%,100%{transform:rotate(-8deg)}50%{transform:rotate(8deg)}}

/* cheeks warm when he speaks */
.mdBlush{transition:opacity .5s var(--e-out,ease)}
#mondul.speaking .mdBlush{opacity:.72}

/* what he was dropped on, in the panel */
.mdpSubject{background:rgba(31,122,90,.07);border-left:2px solid var(--emerald);
 border-radius:0 10px 10px 0;padding:10px 13px;margin:0 0 12px}
.mdpSubject h4{font-size:.86rem;color:var(--forest);margin:0 0 5px;font-weight:600}
.mdpSubject p{font-size:.8rem;line-height:1.6;color:var(--muted);margin:0}
.mdpWhat{font-size:.68rem;letter-spacing:.13em;text-transform:uppercase;color:var(--muted);
 font-weight:700;margin:0 0 8px}
body.km .mdpWhat,body.zh .mdpWhat{text-transform:none;letter-spacing:.02em}
.mdpVoice{font-size:.7rem;color:var(--muted);margin:0 18px 2px;line-height:1.5;font-style:italic}

@media(prefers-reduced-motion:reduce){
 .mdLeaf{animation:none!important}
 .mdArmL,.mdArmR{transition:none!important;transform:none!important}
}

/* ============================================================
   SAMPEAH — the Khmer greeting
   ------------------------------------------------------------
   Palms together at the chest, head lowered slightly, a small bow
   from the waist. He is the province's ambassador on a Cambodian
   platform; greeting with a wave would have been a small piece of
   carelessness.

   The height of the hands carries meaning in Cambodia — chest for
   a peer, higher for elders, monks and royalty. His sits at chest
   level, which is the correct register for greeting a visitor.

   Note the arm origin: 50% 12% is the SHOULDER, not the centre of
   the limb. Rotating a limb about its middle makes it slide rather
   than swing, and the hands never meet.
   ============================================================ */
.mdArmL,.mdArmR{transform-box:fill-box;transform-origin:50% 12%;
 transition:transform .75s cubic-bezier(.34,1.56,.64,1)}

#mondul.sampeah .mdArmL{transform:rotate(-57deg) translate(1px,-4px)}
#mondul.sampeah .mdArmR{transform:rotate(57deg)  translate(-1px,-4px)}
/* the bow: forward from the waist, and the head dips with it */
#mondul.sampeah .mdBot{transform:translateY(4px) rotate(1.5deg) scale(1.02);
 transition:transform .75s cubic-bezier(.34,1.56,.64,1)}
#mondul.sampeah .mdHeadLook{--hy:2.5px; --hr:0deg}
/* eyes soften — a sampeah is given with the eyes lowered */
#mondul.sampeah .mdEye{transform:scaleY(.55)}
#mondul.sampeah .mdBlush{opacity:.66}
/* he holds still for it; the idle tilt would spoil the gesture */
#mondul.sampeah .mdHeadIdle{animation-play-state:paused}

@media(prefers-reduced-motion:reduce){
 #mondul.sampeah .mdArmL,#mondul.sampeah .mdArmR,
 #mondul.sampeah .mdBot{transition:none!important}
}

/* ---- wider context, and outside authorities ---- */
.mdpWide{font-size:.66rem;letter-spacing:.13em;text-transform:uppercase;color:var(--muted);
 font-weight:700;margin:16px 0 8px;padding-top:12px;border-top:1px solid var(--line)}
body.km .mdpWide,body.zh .mdpWide{text-transform:none;letter-spacing:.02em}
.mdpDim{opacity:.62}
.mdpDim h4{font-weight:500}
.mdpOut{margin-top:4px}
.mdpAuth{display:block;text-decoration:none;padding:9px 12px;border-radius:10px;
 background:rgba(31,122,90,.06);margin-bottom:6px;
 transition:background .24s var(--e-swift,ease),transform .34s var(--e-out,ease)}
.mdpAuth:hover{background:rgba(31,122,90,.13);transform:translateX(4px)}
.mdpAuth strong{display:block;font-size:.8rem;color:var(--forest);font-weight:600;line-height:1.4}
.mdpAuth span{display:block;font-size:.68rem;color:var(--emerald);margin-top:2px}
.mdpOutNote{font-size:.68rem;color:var(--muted);line-height:1.55;margin:8px 0 0;font-style:italic}
@media(prefers-reduced-motion:reduce){ .mdpAuth:hover{transform:none} }

/* ============================================================
   PANEL PLACEMENT
   Four positions, chosen by measurement in mondul.js. The default
   used to be "always above", which put the panel off screen the
   moment Mondul was dragged near the top of the window.
   ============================================================ */
.mdPanel.mdUp{bottom:100%;top:auto;margin:0 0 16px;transform-origin:100% 100%}
.mdPanel.mdDown{top:100%;bottom:auto;margin:16px 0 0;transform-origin:100% 0}
.mdPanel.mdSide{bottom:0;top:auto;right:100%;margin:0 16px 0 0;transform-origin:100% 100%}
/* dragged to the left edge — open toward the right instead */
.mdPanel.mdRight{right:auto;left:0}
.mdPanel.mdSide.mdRight{right:auto;left:100%;margin:0 0 0 16px;transform-origin:0 100%}
.mdPanel.mdDown{transform:translate3d(0,-14px,0) scale(.94)}
#mondul.mdopen .mdPanel.mdDown{transform:none}
.mdPanel.mdSide{transform:translate3d(14px,0,0) scale(.94)}
#mondul.mdopen .mdPanel.mdSide{transform:none}
.mdPanel.mdSide.mdRight{transform:translate3d(-14px,0,0) scale(.94)}
#mondul.mdopen .mdPanel.mdSide.mdRight{transform:none}

/* On a phone the panel is pinned above the keyboard-safe area and
   the measured placement does not apply. */
@media(max-width:760px){
  .mdPanel,.mdPanel.mdUp,.mdPanel.mdDown,.mdPanel.mdSide,.mdPanel.mdRight{
    position:fixed;right:12px;left:12px;top:auto;bottom:96px;width:auto;margin:0;
    transform:translate3d(0,14px,0) scale(.96);transform-origin:50% 100%}
  #mondul.mdopen .mdPanel{transform:none}
}

/* ============================================================
   POSES
   Five postures on one rig. Each is a transform on a group that
   carries no SVG transform attribute — the same discipline as the
   hero, for the same reason.
   ============================================================ */
#mondul{transition:transform .6s var(--e-out,cubic-bezier(.25,1,.5,1))}

/* STAND — the default hover, thrusters lit */
#mondul.stand .mdFloat{animation-duration:3.6s}

/* SIT — he settles onto the ground, thrusters dim, arms rest */
#mondul.sit .mdFloat{animation-play-state:paused;transform:translateY(9px)}
#mondul.sit .mdBot{transform:translateY(6px) scaleY(.94)}
#mondul.sit .mdArmL{transform:rotate(-14deg) translateY(3px)}
#mondul.sit .mdArmR{transform:rotate(14deg) translateY(3px)}
#mondul.sit .mdGlow{opacity:.18!important;animation:none}
#mondul.sit .mdShadow{opacity:.42;transform:scaleX(1.12)}
#mondul.sit .mdHeadLook{--hy:2px}

/* JUMP — a real arc: fast up, hang, quick down, squash on landing */
#mondul.jump .mdFloat{animation:mdJump .9s cubic-bezier(.3,0,.4,1)}
@keyframes mdJump{
 0%  {transform:translateY(0) scaleY(.92)}
 18% {transform:translateY(-26px) scaleY(1.06)}
 42% {transform:translateY(-32px) scaleY(1)}
 70% {transform:translateY(0) scaleY(.88)}
 85% {transform:translateY(-4px) scaleY(1.02)}
 100%{transform:translateY(0) scaleY(1)}
}
#mondul.jump .mdArmL{transform:rotate(-38deg)}
#mondul.jump .mdArmR{transform:rotate(38deg)}

/* WALK — a gentle two-beat with the arms counter-swinging */
#mondul.walk .mdFloat{animation:mdWalk .62s ease-in-out infinite}
@keyframes mdWalk{
 0%,100%{transform:translateY(0) rotate(-1.4deg)}
 50%    {transform:translateY(-4px) rotate(1.4deg)}
}
#mondul.walk .mdArmL{animation:mdSwingA .62s ease-in-out infinite}
#mondul.walk .mdArmR{animation:mdSwingB .62s ease-in-out infinite}
@keyframes mdSwingA{0%,100%{transform:rotate(20deg)}50%{transform:rotate(-18deg)}}
@keyframes mdSwingB{0%,100%{transform:rotate(-18deg)}50%{transform:rotate(20deg)}}

/* RUN — faster, leaning into it, arms swept back */
#mondul.run .mdFloat{animation:mdWalk .34s ease-in-out infinite}
#mondul.run .mdBot{transform:rotate(-9deg) scale(1.03)}
#mondul.run .mdArmL{animation:mdSwingA .34s ease-in-out infinite}
#mondul.run .mdArmR{animation:mdSwingB .34s ease-in-out infinite}
#mondul.run .mdGlow{opacity:1!important}

@media(prefers-reduced-motion:reduce){
 #mondul.sit,#mondul.jump,#mondul.walk,#mondul.run{transition:none!important}
 #mondul.jump .mdFloat,#mondul.walk .mdFloat,#mondul.run .mdFloat{animation:none!important}
}

/* ============================================================
   POSTURES — STAND, SIT, JUMP, WALK, RUN
   ------------------------------------------------------------
   These were being asked for and never arrived. The script has
   called pose('walk') and pose('sit') for some time; the classes
   it added were styled by nothing at all, so every posture was a
   no-op and he stayed a floating bust for the whole session.

   Two things had to be true before this could work:

   1. HE NEEDED LEGS. A walk cycle is legs. Without them the only
      honest reading of "walk" is a slide, which is what he did.

   2. ONE WRITER PER PROPERTY. Position is written by the drag
      controller on #mondul itself. So every posture animates the
      groups INSIDE the svg — .mdLegL, .mdLegR, .mdBody — and never
      the host. A pose and a glide can therefore run at the same
      time without either erasing the other, which is exactly what
      a walk-to-the-reader is: a glide plus a leg cycle.

   Only transform and opacity, so all of it is composited.
   ============================================================ */

/* the two legs, and the pair of them as a unit */
.mdLegL,.mdLegR{transform-box:fill-box;transform-origin:50% 8%}

/* ---- STAND: settle back to neutral with a little weight ---- */
#mondul.mdStand .mdLegL,#mondul.mdStand .mdLegR{animation:mdSettle .8s var(--e-spring,ease)}
@keyframes mdSettle{0%{transform:rotate(6deg)}60%{transform:rotate(-3deg)}100%{transform:none}}

/* ---- WALK: the legs alternate, the body rises on each step ----
   Half a cycle apart, which is what makes it read as walking
   rather than as both legs waving. */
#mondul.mdWalk .mdLegL{animation:mdStep .62s ease-in-out infinite}
#mondul.mdWalk .mdLegR{animation:mdStep .62s ease-in-out infinite -.31s}
#mondul.mdWalk .mdLean{animation:mdBob .31s ease-in-out infinite}
#mondul.mdWalk .mdArmL{animation:mdSwing .62s ease-in-out infinite -.31s}
#mondul.mdWalk .mdArmR{animation:mdSwing .62s ease-in-out infinite}
@keyframes mdStep{
 0%,100%{transform:rotate(24deg)}
 50%    {transform:rotate(-24deg)}
}
@keyframes mdBob{0%,100%{transform:translateY(0)}50%{transform:translateY(-2.5px)}}
@keyframes mdSwing{0%,100%{transform:rotate(-16deg)}50%{transform:rotate(16deg)}}

/* ---- RUN: same cycle, faster, wider, and leaning into it ----
   The forward lean is the difference between running and walking
   quickly. Real runners fall forward and catch themselves. */
#mondul.mdRun .mdLegL{animation:mdStepFast .3s ease-in-out infinite}
#mondul.mdRun .mdLegR{animation:mdStepFast .3s ease-in-out infinite -.15s}
#mondul.mdRun .mdArmL{animation:mdSwingFast .3s ease-in-out infinite -.15s}
#mondul.mdRun .mdArmR{animation:mdSwingFast .3s ease-in-out infinite}
#mondul.mdRun .mdLean{animation:mdRunLean .3s ease-in-out infinite}
@keyframes mdStepFast{
 0%,100%{transform:rotate(42deg)}
 50%    {transform:rotate(-42deg)}
}
@keyframes mdSwingFast{0%,100%{transform:rotate(-34deg)}50%{transform:rotate(34deg)}}
@keyframes mdRunLean{
 0%,100%{transform:translateY(0) rotate(7deg)}
 50%    {transform:translateY(-4px) rotate(7deg)}
}

/* ---- SIT: knees forward, body drops, the shadow tightens ----
   Sitting is not just lower. The legs go out in front, the torso
   comes down to meet them, and the contact shadow shrinks because
   he is closer to the ground. */
#mondul.mdSit .mdLegL{transform:rotate(72deg) translateY(1px)}
#mondul.mdSit .mdLegR{transform:rotate(66deg) translateY(1px)}
#mondul.mdSit .mdLean{transform:translateY(9px)}
#mondul.mdSit .mdShadow{transform:scaleX(.82);opacity:.34}
#mondul.mdSit .mdArmL{transform:rotate(-22deg)}
#mondul.mdSit .mdArmR{transform:rotate(22deg)}
#mondul.mdSit .mdLegL,#mondul.mdSit .mdLegR,#mondul.mdSit .mdLean,
#mondul.mdSit .mdArmL,#mondul.mdSit .mdArmR{
  transition:transform .55s var(--e-spring,cubic-bezier(.34,1.56,.64,1))}

/* ---- JUMP: crouch, launch, tuck, land ----
   The crouch before and the squash after are what sell it; a
   symmetrical up-and-down reads as a bounce, not a jump. */
#mondul.mdJump .mdLean{animation:mdLeap .9s cubic-bezier(.3,1.4,.5,1)}
#mondul.mdJump .mdLegL{animation:mdTuckL .9s cubic-bezier(.3,1.4,.5,1)}
#mondul.mdJump .mdLegR{animation:mdTuckR .9s cubic-bezier(.3,1.4,.5,1)}
#mondul.mdJump .mdShadow{animation:mdShadowDip .9s cubic-bezier(.3,1.4,.5,1)}
@keyframes mdLeap{
 0%  {transform:translateY(0) scaleY(1)}
 14% {transform:translateY(4px) scaleY(.9)}     /* crouch */
 46% {transform:translateY(-26px) scaleY(1.06)} /* apex */
 74% {transform:translateY(2px) scaleY(.93)}    /* land, squash */
 100%{transform:none}
}
@keyframes mdTuckL{0%{transform:none}14%{transform:rotate(18deg)}46%{transform:rotate(-30deg)}100%{transform:none}}
@keyframes mdTuckR{0%{transform:none}14%{transform:rotate(14deg)}46%{transform:rotate(-26deg)}100%{transform:none}}
@keyframes mdShadowDip{
 0%,100%{transform:none;opacity:.28}
 46%    {transform:scale(.7);opacity:.12}
}

/* Anything that moves him also moves his feet. When he glides to
   the reader the walk class is on, so the cycle runs over the
   glide — two different elements, two different properties. */
@media (prefers-reduced-motion:reduce){
  #mondul.mdWalk *,#mondul.mdRun *,#mondul.mdJump *,#mondul.mdStand *{
    animation:none!important}
  #mondul.mdSit .mdLegL,#mondul.mdSit .mdLegR,#mondul.mdSit .mdLean{transition:none}
}

/* ============================================================
   DANCING, SLEEPING, EXERCISING
   ------------------------------------------------------------
   Five postures were enough to prove he was animate. These are
   what make him company.

   Each dance is a genuinely different motion rather than the same
   bounce at three speeds — that is the whole point of "all kinds".
   The parts move against each other: in the sway the hips lead and
   the head follows a beat late, in the robot everything snaps on
   the beat with nothing in between, in the spin the whole figure
   turns while the arms trail. Give three dances the same timing
   function and they read as one dance with the speed changed.

   Same rules as the other poses: only groups inside the svg are
   touched, never the host, so a dance can run while he is being
   dragged or walked. Transform and opacity only.
   ============================================================ */

/* ---- DANCE 1 · SWAY. Loose, weight shifting foot to foot,
        the head arriving a beat after the body. ---- */
#mondul.mdDanceSway .mdLean{animation:mdSway 1.1s ease-in-out infinite}
#mondul.mdDanceSway .mdHeadIdle{animation:mdSwayHead 1.1s ease-in-out infinite -.14s}
#mondul.mdDanceSway .mdArmL{animation:mdSwayArmL 1.1s ease-in-out infinite}
#mondul.mdDanceSway .mdArmR{animation:mdSwayArmR 1.1s ease-in-out infinite}
#mondul.mdDanceSway .mdLegL{animation:mdSwayLegL 1.1s ease-in-out infinite}
#mondul.mdDanceSway .mdLegR{animation:mdSwayLegR 1.1s ease-in-out infinite}
@keyframes mdSway{
 0%,100%{transform:translateX(-5px) rotate(-4deg)}
 50%    {transform:translateX(5px) rotate(4deg)}
}
@keyframes mdSwayHead{
 0%,100%{transform:translateX(3px) rotate(5deg)}
 50%    {transform:translateX(-3px) rotate(-5deg)}
}
@keyframes mdSwayArmL{0%,100%{transform:rotate(-42deg)}50%{transform:rotate(12deg)}}
@keyframes mdSwayArmR{0%,100%{transform:rotate(-12deg)}50%{transform:rotate(42deg)}}
@keyframes mdSwayLegL{0%,100%{transform:rotate(-13deg)}50%{transform:rotate(9deg)}}
@keyframes mdSwayLegR{0%,100%{transform:rotate(-9deg)}50%{transform:rotate(13deg)}}

/* ---- DANCE 2 · THE ROBOT. `steps(1)` is the whole joke: the
        transform jumps to the next value and holds, so there is no
        interpolation at all. He is a robot; he is allowed. ---- */
#mondul.mdDanceRobot .mdArmL{animation:mdRoboL 1.6s steps(1) infinite}
#mondul.mdDanceRobot .mdArmR{animation:mdRoboR 1.6s steps(1) infinite}
#mondul.mdDanceRobot .mdHeadIdle{animation:mdRoboHead 1.6s steps(1) infinite}
#mondul.mdDanceRobot .mdLean{animation:mdRoboBody 1.6s steps(1) infinite}
@keyframes mdRoboL{0%{transform:rotate(0)}25%{transform:rotate(-88deg)}50%{transform:rotate(-40deg)}75%{transform:rotate(-88deg)}100%{transform:rotate(0)}}
@keyframes mdRoboR{0%{transform:rotate(-88deg)}25%{transform:rotate(0)}50%{transform:rotate(88deg)}75%{transform:rotate(0)}100%{transform:rotate(-88deg)}}
@keyframes mdRoboHead{0%{transform:rotate(-9deg)}25%{transform:rotate(9deg)}50%{transform:rotate(-9deg)}75%{transform:rotate(9deg)}100%{transform:rotate(-9deg)}}
@keyframes mdRoboBody{0%{transform:translateX(-4px)}50%{transform:translateX(4px)}100%{transform:translateX(-4px)}}

/* ---- DANCE 3 · SPIN. He turns on the spot; the arms trail
        outward because they are not being held in. ---- */
#mondul.mdDanceSpin .mdLean{animation:mdSpin 1.4s cubic-bezier(.5,0,.5,1) infinite}
#mondul.mdDanceSpin .mdArmL{animation:mdSpinArmL 1.4s ease-in-out infinite}
#mondul.mdDanceSpin .mdArmR{animation:mdSpinArmR 1.4s ease-in-out infinite}
#mondul.mdDanceSpin .mdShadow{animation:mdSpinShade 1.4s ease-in-out infinite}
@keyframes mdSpin{
 0%  {transform:rotateY(0) translateY(0)}
 45% {transform:rotateY(180deg) translateY(-7px)}
 100%{transform:rotateY(360deg) translateY(0)}
}
@keyframes mdSpinArmL{0%,100%{transform:rotate(-56deg)}50%{transform:rotate(-74deg)}}
@keyframes mdSpinArmR{0%,100%{transform:rotate(56deg)}50%{transform:rotate(74deg)}}
@keyframes mdSpinShade{0%,100%{transform:scaleX(1);opacity:.28}45%{transform:scaleX(.6);opacity:.18}}

/* ---- DANCE 4 · HOP. A khmer-ish shoulder-and-heel step: he
        rises on alternate feet with a small skip. ---- */
#mondul.mdDanceHop .mdLean{animation:mdHopBody .58s cubic-bezier(.3,1.3,.5,1) infinite}
#mondul.mdDanceHop .mdLegL{animation:mdHopL .58s cubic-bezier(.3,1.3,.5,1) infinite}
#mondul.mdDanceHop .mdLegR{animation:mdHopL .58s cubic-bezier(.3,1.3,.5,1) infinite -.29s}
#mondul.mdDanceHop .mdArmL{animation:mdHopArm .58s ease-in-out infinite -.29s}
#mondul.mdDanceHop .mdArmR{animation:mdHopArm .58s ease-in-out infinite}
@keyframes mdHopBody{0%,100%{transform:translateY(0)}45%{transform:translateY(-9px)}}
@keyframes mdHopL{0%,100%{transform:rotate(0)}45%{transform:rotate(-34deg)}}
@keyframes mdHopArm{0%,100%{transform:rotate(-8deg)}50%{transform:rotate(-62deg)}}

/* ---- SLEEP. He sits down, the head tips onto one side, the
        antenna droops, the eyes close, and three z's rise. The
        breathing is deliberately slower than his idle float —
        that difference is what reads as asleep rather than idle. */
#mondul.mdSleep .mdLegL{transform:rotate(74deg)}
#mondul.mdSleep .mdLegR{transform:rotate(68deg)}
#mondul.mdSleep .mdArmL{transform:rotate(-30deg)}
#mondul.mdSleep .mdArmR{transform:rotate(30deg)}
#mondul.mdSleep .mdLean{transform:translateY(10px);animation:mdBreathe 4.2s ease-in-out infinite}
#mondul.mdSleep .mdHeadIdle{transform:rotate(-15deg) translateY(2px)}
#mondul.mdSleep .mdAnt{animation:mdDroop 4.2s ease-in-out infinite}
#mondul.mdSleep .mdShadow{transform:scaleX(.8);opacity:.34}
#mondul.mdSleep .mdEyes{transform:scaleY(.08);transform-box:fill-box;transform-origin:50% 62%}
#mondul.mdSleep .mdBlush{opacity:.6}
#mondul.mdSleep .mdLegL,#mondul.mdSleep .mdLegR,#mondul.mdSleep .mdArmL,
#mondul.mdSleep .mdArmR,#mondul.mdSleep .mdHeadIdle,#mondul.mdSleep .mdEyes{
  transition:transform .9s cubic-bezier(.22,1,.36,1)}
@keyframes mdBreathe{
 0%,100%{transform:translateY(10px) scaleY(1)}
 50%    {transform:translateY(12px) scaleY(1.035)}
}
@keyframes mdDroop{0%,100%{transform:rotate(0)}50%{transform:rotate(7deg)}}
/* the z's — three, each rising and fading a beat after the last.
   The group sits outside .mdFloat so his breathing does not carry
   them, and it never takes pointer events. */
.mdZzz{pointer-events:none}
.mdZ{opacity:0}
#mondul.mdSleep .mdZ{animation:mdZfloat 3s ease-out infinite}
#mondul.mdSleep .mdZ:nth-of-type(2){animation-delay:1s}
#mondul.mdSleep .mdZ:nth-of-type(3){animation-delay:2s}
@keyframes mdZfloat{
 0%  {opacity:0; transform:translate(0,0) scale(.6)}
 22% {opacity:.95}
 100%{opacity:0; transform:translate(13px,-30px) scale(1.25)}
}

/* ---- EXERCISE. Three drills, cycled. Star jumps, squats, and a
        stretch — the three things a small robot would obviously do
        if it had decided to get in shape. ---- */
#mondul.mdExJack .mdLegL{animation:mdJackL .52s ease-in-out infinite}
#mondul.mdExJack .mdLegR{animation:mdJackR .52s ease-in-out infinite}
#mondul.mdExJack .mdArmL{animation:mdJackArmL .52s ease-in-out infinite}
#mondul.mdExJack .mdArmR{animation:mdJackArmR .52s ease-in-out infinite}
#mondul.mdExJack .mdLean{animation:mdJackBody .52s ease-in-out infinite}
@keyframes mdJackL{0%,100%{transform:rotate(0)}50%{transform:rotate(-26deg)}}
@keyframes mdJackR{0%,100%{transform:rotate(0)}50%{transform:rotate(26deg)}}
@keyframes mdJackArmL{0%,100%{transform:rotate(0)}50%{transform:rotate(-128deg)}}
@keyframes mdJackArmR{0%,100%{transform:rotate(0)}50%{transform:rotate(128deg)}}
@keyframes mdJackBody{0%,100%{transform:translateY(0)}50%{transform:translateY(-6px)}}

#mondul.mdExSquat .mdLean{animation:mdSquat 1.1s ease-in-out infinite}
#mondul.mdExSquat .mdLegL{animation:mdSquatLeg 1.1s ease-in-out infinite}
#mondul.mdExSquat .mdLegR{animation:mdSquatLeg 1.1s ease-in-out infinite}
#mondul.mdExSquat .mdArmL{animation:mdSquatArm 1.1s ease-in-out infinite}
#mondul.mdExSquat .mdArmR{animation:mdSquatArm 1.1s ease-in-out infinite}
@keyframes mdSquat{0%,100%{transform:translateY(0) scaleY(1)}50%{transform:translateY(11px) scaleY(.9)}}
@keyframes mdSquatLeg{0%,100%{transform:rotate(0)}50%{transform:rotate(24deg)}}
@keyframes mdSquatArm{0%,100%{transform:rotate(0)}50%{transform:rotate(-84deg)}}

#mondul.mdExStretch .mdArmL{animation:mdStretchL 2.4s ease-in-out infinite}
#mondul.mdExStretch .mdArmR{animation:mdStretchR 2.4s ease-in-out infinite}
#mondul.mdExStretch .mdLean{animation:mdStretchBody 2.4s ease-in-out infinite}
#mondul.mdExStretch .mdHeadIdle{animation:mdStretchHead 2.4s ease-in-out infinite}
@keyframes mdStretchL{0%,100%{transform:rotate(0)}30%{transform:rotate(-150deg)}60%{transform:rotate(-40deg)}}
@keyframes mdStretchR{0%,100%{transform:rotate(0)}30%{transform:rotate(150deg)}60%{transform:rotate(40deg)}}
@keyframes mdStretchBody{0%,100%{transform:rotate(0)}30%{transform:rotate(-7deg)}60%{transform:rotate(7deg)}}
@keyframes mdStretchHead{0%,100%{transform:rotate(0)}30%{transform:rotate(6deg)}60%{transform:rotate(-6deg)}}

@media (prefers-reduced-motion:reduce){
  #mondul.mdDanceSway *,#mondul.mdDanceRobot *,#mondul.mdDanceSpin *,
  #mondul.mdDanceHop *,#mondul.mdExJack *,#mondul.mdExSquat *,
  #mondul.mdExStretch *,#mondul.mdSleep *{animation:none!important}
}

/* ============================================================
   COOKING, AND THEN EATING
   ------------------------------------------------------------
   The kitchen is drawn once and hidden. It appears only for the
   two poses that need it, and each part animates on its own
   clock — the fire is fast and irregular, the steam is slow and
   staggered, the pot barely moves. Giving them one shared timing
   would make the whole thing pulse as a unit, which is the exact
   look of a sprite rather than a scene.
   ============================================================ */
.mdKit{opacity:0;pointer-events:none;transition:opacity .5s var(--e-out,ease)}
.mdPot,.mdSteam,.mdFire,.mdBowl{opacity:0}
#mondul.mdCook .mdKit,#mondul.mdEat .mdKit{opacity:1}
#mondul.mdCook .mdPot,#mondul.mdCook .mdSteam,#mondul.mdCook .mdFire{opacity:1}
#mondul.mdEat .mdBowl{opacity:1}

/* the fire — quick, uneven, never the same two beats running */
.mdFire{transform-box:fill-box;transform-origin:50% 100%}
#mondul.mdCook .mdFire{animation:mdFlame .42s ease-in-out infinite alternate}
@keyframes mdFlame{
 0%  {transform:scaleY(.88) scaleX(1.04) translateY(1px)}
 100%{transform:scaleY(1.12) scaleX(.94)}
}
/* the pot rocks, barely */
.mdPot{transform-box:fill-box;transform-origin:50% 100%}
#mondul.mdCook .mdPot{animation:mdPotRock 1.9s ease-in-out infinite}
@keyframes mdPotRock{0%,100%{transform:rotate(-1.2deg)}50%{transform:rotate(1.2deg)}}
/* steam — each wisp rises on its own delay and fades out at the top */
.mdWisp{opacity:0}
#mondul.mdCook .mdWisp{animation:mdSteamUp 2.6s ease-out infinite}
#mondul.mdCook .mdWisp:nth-of-type(2){animation-delay:.85s}
#mondul.mdCook .mdWisp:nth-of-type(3){animation-delay:1.7s}
@keyframes mdSteamUp{
 0%  {opacity:0;   transform:translateY(6px) scaleX(.7)}
 25% {opacity:.8}
 100%{opacity:0;   transform:translateY(-16px) scaleX(1.3)}
}

/* HE COOKS WITH HIS HANDS. He crouches at the pot, one arm
   stirring in a slow circle, head down over the work. */
#mondul.mdCook .mdLean{transform:translate(9px,7px) scale(.96)}
#mondul.mdCook .mdHeadIdle{transform:rotate(-13deg)}
#mondul.mdCook .mdLegL{transform:rotate(48deg)}
#mondul.mdCook .mdLegR{transform:rotate(40deg)}
#mondul.mdCook .mdArmR{transform:rotate(6deg)}
#mondul.mdCook .mdArmL{animation:mdStir 1.5s linear infinite}
@keyframes mdStir{
 0%  {transform:rotate(-24deg) translate(0,0)}
 25% {transform:rotate(-34deg) translate(-2px,2px)}
 50% {transform:rotate(-24deg) translate(0,4px)}
 75% {transform:rotate(-14deg) translate(2px,2px)}
 100%{transform:rotate(-24deg) translate(0,0)}
}
#mondul.mdCook .mdLean,#mondul.mdCook .mdHeadIdle,
#mondul.mdCook .mdLegL,#mondul.mdCook .mdLegR,#mondul.mdCook .mdArmR{
 transition:transform .7s var(--e-spring,cubic-bezier(.34,1.56,.64,1))}

/* EATING. Sitting, bowl in the left hand, the right lifting to the
   mouth on a slow four-second cycle — with a pause at the top,
   because eating is mostly chewing. */
#mondul.mdEat .mdLegL{transform:rotate(70deg)}
#mondul.mdEat .mdLegR{transform:rotate(64deg)}
#mondul.mdEat .mdLean{transform:translateY(8px)}
#mondul.mdEat .mdArmL{transform:rotate(34deg)}
#mondul.mdEat .mdShadow{transform:scaleX(.85);opacity:.32}
#mondul.mdEat .mdArmR{animation:mdSpoon 2.8s ease-in-out infinite}
@keyframes mdSpoon{
 0%,12% {transform:rotate(46deg)}          /* down at the bowl */
 34%,58%{transform:rotate(-58deg)}         /* up, and held — chewing */
 82%,100%{transform:rotate(46deg)}
}
#mondul.mdEat .mdHeadIdle{animation:mdChew 2.8s ease-in-out infinite}
@keyframes mdChew{
 0%,30%  {transform:none}
 38%,56% {transform:translateY(.8px) scaleY(.985)}
 64%,100%{transform:none}
}
#mondul.mdEat .mdBlush{opacity:.62}
#mondul.mdEat .mdLegL,#mondul.mdEat .mdLegR,#mondul.mdEat .mdLean,
#mondul.mdEat .mdArmL{transition:transform .7s var(--e-spring,cubic-bezier(.34,1.56,.64,1))}

@media (prefers-reduced-motion:reduce){
  #mondul.mdCook *,#mondul.mdEat *{animation:none!important}
}

/* ============================================================
   DROWSY — THE STATE BEFORE SLEEP
   ------------------------------------------------------------
   He went from wide awake to asleep in one frame, which is the one
   thing living creatures never do. Tiredness arrives first.

   Three signals, and all three matter:
     · the EYES go to half-mast and stay there
     · the HEAD nods and catches itself, on an uneven clock — the
       catch is the whole point, because a smooth nod reads as
       agreement and a jerky one reads as fighting sleep
     · he YAWNS, mouth wide, arms coming up

   He can be drowsy without being asleep. That is deliberate: it
   lets him be a little tired in the middle of an ordinary session
   and then shake it off, which is far more alive than a character
   who is only ever fully on or fully off.
   ============================================================ */

/* eyes at half-mast — scaled down from the TOP, so the lower lid
   stays put and the upper one comes down. Scaling from the centre
   would close them symmetrically, which looks like a blink held
   too long rather than a heavy eyelid. */
.mdEyes{transform-box:fill-box;transform-origin:50% 22%}
#mondul.mdDrowsy .mdEyes{transform:scaleY(.46);
 transition:transform .8s var(--e-out,ease)}
#mondul.mdDrowsy .mdBlush{opacity:.58;transition:opacity .8s ease}

/* the nod, and the catch. Long slow droop, sharp recovery, pause —
   then it happens again slightly differently because the second
   keyframe set runs on a different multiple of the same duration. */
#mondul.mdDrowsy .mdHeadIdle{animation:mdNod 5.4s ease-in-out infinite}
@keyframes mdNod{
 0%,14%  {transform:rotate(0) translateY(0)}
 40%     {transform:rotate(11deg) translateY(3px)}   /* going... */
 46%     {transform:rotate(-3deg) translateY(-1px)}  /* caught it */
 52%     {transform:rotate(1deg)}
 74%     {transform:rotate(9deg) translateY(2px)}    /* going again */
 79%     {transform:rotate(-2deg)}
 100%    {transform:rotate(0) translateY(0)}
}
/* the whole body sags a little, slower than the nod so the two
   never line up and it never reads as one pulse */
#mondul.mdDrowsy .mdLean{animation:mdSag 7.1s ease-in-out infinite}
@keyframes mdSag{
 0%,100%{transform:translateY(0)}
 50%    {transform:translateY(3px) scaleY(.99)}
}
/* the antenna gives up before he does */
#mondul.mdDrowsy .mdAnt{animation:mdAntDroop 5.4s ease-in-out infinite}
@keyframes mdAntDroop{
 0%,14%{transform:rotate(0)}
 40%   {transform:rotate(13deg)}
 50%   {transform:rotate(-4deg)}
 100%  {transform:rotate(0)}
}

/* THE YAWN. The visor stretches open, the eyes squeeze shut, the
   arms come up and back. Held at full stretch for a beat, because
   a yawn that snaps shut immediately is a grimace. */
#mondul.mdYawn .mdVisorMouth,
#mondul.mdYawn .mdEyes{animation:mdYawnEyes 1.9s ease-in-out}
@keyframes mdYawnEyes{
 0%     {transform:scaleY(.46)}
 22%,62%{transform:scaleY(.12)}     /* screwed shut */
 100%   {transform:scaleY(.46)}
}
#mondul.mdYawn .mdHeadIdle{animation:mdYawnHead 1.9s cubic-bezier(.22,1,.36,1)}
@keyframes mdYawnHead{
 0%     {transform:none}
 26%,58%{transform:rotate(-9deg) translateY(-2px)}   /* head back */
 100%   {transform:none}
}
#mondul.mdYawn .mdArmL{animation:mdYawnArmL 1.9s cubic-bezier(.22,1,.36,1)}
#mondul.mdYawn .mdArmR{animation:mdYawnArmR 1.9s cubic-bezier(.22,1,.36,1)}
@keyframes mdYawnArmL{0%{transform:none}30%,58%{transform:rotate(-104deg)}100%{transform:none}}
@keyframes mdYawnArmR{0%{transform:none}30%,58%{transform:rotate(104deg)}100%{transform:none}}
/* a small puff of air, so the yawn has an outward gesture */
#mondul.mdYawn .mdWisp:first-of-type{
 opacity:0;animation:mdYawnPuff 1.9s ease-out}
@keyframes mdYawnPuff{
 0%,24%{opacity:0}
 40%   {opacity:.5}
 100%  {opacity:0}
}

@media (prefers-reduced-motion:reduce){
  #mondul.mdDrowsy *,#mondul.mdYawn *{animation:none!important}
  #mondul.mdDrowsy .mdEyes{transform:scaleY(.46)}
}

/* ============================================================
   THE BICYCLE — WHAT HE DOES WHEN HE IS BORED
   ------------------------------------------------------------
   Boredom sits between "still here" and "gone". He is not tired
   and not hungry; there is simply nothing happening. So he gets
   the bicycle out and rides up and down the edge of the page.

   The important decision is that he COVERS GROUND. Pedalling on
   the spot is a novelty loop; actually travelling three hundred
   pixels and coming back is a character with somewhere to be. That
   works because the glide and the pedal cycle are written by
   different things — the drag controller moves the host, these
   rules move the parts inside the drawing — so they compose
   instead of overwriting each other.
   ============================================================ */
.mdBike{opacity:0;pointer-events:none;transition:opacity .45s var(--e-out,ease)}
.mdKit2{pointer-events:none}
#mondul.mdRide .mdBike{opacity:1}

/* wheels turn. transform-box:fill-box puts the origin at the centre
   of each wheel rather than at the origin of the whole svg, which is
   the difference between a wheel rolling and a wheel orbiting. */
.mdWheel{transform-box:fill-box;transform-origin:50% 50%}
/* Front and rear are named separately so a later change can treat
   them differently — a front wheel that wobbles on a rut, a rear one
   that skids on the turn. For now they roll identically, and saying
   so here is cheaper than discovering the classes do nothing. */
.mdWheelR,.mdWheelF{transform-box:fill-box}
#mondul.mdRide .mdWheel{animation:mdRoll .5s linear infinite}
@keyframes mdRoll{to{transform:rotate(360deg)}}
/* the crank turns at a third of the wheel speed, which is roughly
   the gearing of an old roadster and, more to the point, is the
   detail that makes the whole thing read as a bicycle */
.mdCrank{transform-box:fill-box;transform-origin:50% 26%}
#mondul.mdRide .mdCrank{animation:mdRoll 1.5s linear infinite}
/* the basket bounces on the rough bits */
#mondul.mdRide .mdBasket{animation:mdBasket .5s ease-in-out infinite}
@keyframes mdBasket{0%,100%{transform:translateY(0)}50%{transform:translateY(-1px)}}

/* HE RIDES IT. Legs bent to the pedals and cycling half a beat
   apart, body pitched forward over the bars, arms down and out. */
#mondul.mdRide .mdLean{transform:translate(2px,-6px) rotate(6deg);
 animation:mdRideBob .5s ease-in-out infinite}
@keyframes mdRideBob{
 0%,100%{transform:translate(2px,-6px) rotate(6deg)}
 50%    {transform:translate(2px,-8px) rotate(6deg)}
}
#mondul.mdRide .mdHeadIdle{transform:rotate(-8deg)}
#mondul.mdRide .mdArmL{transform:rotate(-52deg)}
#mondul.mdRide .mdArmR{transform:rotate(-44deg)}
#mondul.mdRide .mdLegL{animation:mdPedal .5s linear infinite}
#mondul.mdRide .mdLegR{animation:mdPedal .5s linear infinite -.25s}
@keyframes mdPedal{
 0%  {transform:rotate(34deg)}
 25% {transform:rotate(8deg)}
 50% {transform:rotate(30deg)}
 75% {transform:rotate(56deg)}
 100%{transform:rotate(34deg)}
}
#mondul.mdRide .mdShadow{transform:scaleX(1.5);opacity:.22}
#mondul.mdRide .mdHeadIdle,#mondul.mdRide .mdArmL,#mondul.mdRide .mdArmR,
#mondul.mdRide .mdShadow{transition:transform .5s var(--e-spring,cubic-bezier(.34,1.56,.64,1))}

/* TURNING ROUND AT THE END OF THE RUN.
   He rides out to the left and comes back, so on the return leg the
   whole drawing is mirrored. Applied to .mdBot — the one element the
   drag controller does not write — so flipping him cannot disturb
   where he is on the page. */
#mondul.mdRideBack .mdBot{transform:scaleX(-1)}
#mondul.mdRide .mdBot{transition:transform .5s var(--e-out,ease)}

@media (prefers-reduced-motion:reduce){
  #mondul.mdRide *{animation:none!important}
}


/* ---- THE GREETING ----
   He walks to the M, waves, and bobs on the spot. Transform and
   opacity only, and it stops after a few seconds — a mascot that
   never settles is a mascot you end up wanting to close. */
#mondul.mdGreet .mdBot{animation:mdBob 1.5s ease-in-out 3}
@keyframes mdBob{0%,100%{transform:translateY(0) rotate(0)}
  30%{transform:translateY(-5px) rotate(-3.5deg)}
  60%{transform:translateY(-1px) rotate(2.5deg)}}
/* one arm lifts. .mdArmR is the right limb in the built figure. */
#mondul.mdGreet .mdArmR{transform-origin:70% 20%;animation:mdWave .62s ease-in-out 5}
@keyframes mdWave{0%,100%{transform:rotate(0)}50%{transform:rotate(-26deg)}}
/* a small "hello" spark, so the wave reads even at a glance */
#mondul.mdGreet .mdEye{animation:mdBlinkFast 1.1s ease-in-out 3}
@keyframes mdBlinkFast{0%,88%,100%{transform:scaleY(1)}93%{transform:scaleY(.15)}}
@media (prefers-reduced-motion:reduce){
  #mondul.mdGreet .mdBot,#mondul.mdGreet .mdArmR,#mondul.mdGreet .mdEye{animation:none}
}


/* ---- FROZEN, BRIEFLY ----
   He goes WHITE, not glowing. The first version put a radial light
   behind him, which reads as a lamp switching on rather than as
   cold — a glow is something a body emits, and frost is something
   that settles ON it. So the light is gone and the body itself
   frosts over: colour drained, brightened toward white, with a
   faint blue left in the shadows the way ice actually looks.

   filter is a repaint, so it is applied ONCE as a state rather than
   animated. Only the shiver loops, and that is a transform. */
#mondul.mdCold .mdBot{
  animation:mdShiver .13s linear infinite;
  filter:grayscale(.92) brightness(1.5) contrast(.86)
         drop-shadow(0 0 1px rgba(176,214,236,.9));
  transition:filter .45s ease-out}
@keyframes mdShiver{
  0%,100%{transform:translate3d(-.9px,0,0) rotate(-.7deg)}
  50%    {transform:translate3d(.9px,-.5px,0) rotate(.7deg)}
}
/* eyes narrow against the cold */
#mondul.mdCold .mdEye{transform:scaleY(.7)}
/* frost ON the body, not light behind it: a few pale flecks that
   settle over him and go when he thaws */
#mondul.mdCold .mdBot:after{content:"";position:absolute;inset:0;
  pointer-events:none;border-radius:inherit;
  background:
    radial-gradient(circle at 28% 22%, rgba(255,255,255,.85) 0 1.4px, transparent 1.6px),
    radial-gradient(circle at 68% 34%, rgba(255,255,255,.75) 0 1.1px, transparent 1.3px),
    radial-gradient(circle at 44% 62%, rgba(255,255,255,.80) 0 1.3px, transparent 1.5px),
    radial-gradient(circle at 78% 70%, rgba(255,255,255,.70) 0 1px,   transparent 1.2px),
    radial-gradient(circle at 18% 76%, rgba(255,255,255,.65) 0 1px,   transparent 1.2px);
  animation:mdFrost .55s ease-out both}
@keyframes mdFrost{from{opacity:0}to{opacity:1}}
/* shaking it off */
#mondul.mdThaw .mdBot{animation:mdShake .42s cubic-bezier(.36,.07,.19,.97) 2}
@keyframes mdShake{
  0%,100%{transform:rotate(0)}
  25%{transform:rotate(-7deg)} 75%{transform:rotate(7deg)}
}
@media (prefers-reduced-motion:reduce){
  #mondul.mdCold .mdBot,#mondul.mdThaw .mdBot{animation:none}
  #mondul.mdCold .mdBot:after{display:none}
}
