.ks-pet{--ks-pet-scale:1;position:fixed;z-index:2140;width:calc(112px * var(--ks-pet-scale));min-height:calc(112px * var(--ks-pet-scale));touch-action:none;user-select:none;-webkit-user-select:none;-webkit-touch-callout:none;filter:drop-shadow(0 7px 7px rgba(40,24,8,.28))}
.ks-pet__button{display:block;width:calc(112px * var(--ks-pet-scale));height:calc(112px * var(--ks-pet-scale));margin:0;padding:calc(4px * var(--ks-pet-scale)) calc(8px * var(--ks-pet-scale));border:0;background:transparent;cursor:grab;touch-action:none;-webkit-touch-callout:none}
.ks-pet__button:active{cursor:grabbing}
.ks-pet__button:focus-visible{outline:3px solid var(--ks-accent,#16506B);outline-offset:2px;border-radius:14px}
.ks-pet__sprite{--ks-pet-motion-scale:1;display:block;width:calc(96px * var(--ks-pet-scale));height:calc(104px * var(--ks-pet-scale));background-repeat:no-repeat;background-size:calc(768px * var(--ks-pet-scale)) calc(104px * var(--ks-pet-rows,16) * var(--ks-pet-scale));background-position:0 0;transform:scale(var(--ks-pet-motion-scale));transform-origin:50% 65%;-webkit-user-drag:none;-webkit-touch-callout:none}
.ks-pet__bubble{position:absolute;left:12px;bottom:108px;width:min(244px,calc(100vw - 28px));margin:0;padding:12px 14px;background:#FFFDF7;color:#211E19;border:2px solid rgba(33,30,25,.22);border-radius:14px 14px 14px 3px;box-shadow:0 9px 20px rgba(40,24,8,.32);font:600 14px/1.45 'Cabin',Verdana,sans-serif;text-wrap:pretty;pointer-events:none}
.ks-pet--right .ks-pet__bubble{right:12px;left:auto;border-radius:14px 14px 3px 14px}
.ks-pet__bubble[hidden]{display:none}
/* An invitation is pressable, so it has to accept a pointer and look like it will do something.
   Every other bubble stays pointer-events:none so the pet underneath keeps taking the taps. */
.ks-pet__bubble--action{pointer-events:auto;cursor:pointer;border-color:var(--ks-accent);box-shadow:0 9px 20px rgba(22,80,107,.34)}
.ks-pet__bubble--action:focus-visible{outline:3px solid var(--ks-accent);outline-offset:2px}
:root[data-ks-theme="dark"] .ks-pet__bubble--action{border-color:#8FC0D8}
:root[data-ks-theme="dark"] .ks-pet__bubble{background:#211E19;color:#FFFDF7;border-color:rgba(255,253,247,.28)}
@media (max-width:767.98px){.ks-pet{z-index:900}.ks-pet__bubble{left:0;width:min(220px,calc(100vw - 20px))}.ks-pet--right .ks-pet__bubble{right:0;left:auto}}
@media (prefers-reduced-motion:reduce){.ks-pet{filter:drop-shadow(0 5px 5px rgba(40,24,8,.24))}}
/* The energy bar.
 *
 * Six states are a width and a colour, so this is CSS and not six pixel assets: it scales with
 * the pet size setting, translates, stays measurable for contrast in both themes, costs no
 * download, and a colour change is not an art job.
 *
 * It is not part of the pet's own box. It sits above the sprite and is only shown on a
 * deliberate ask - right-click on a desktop, long press on a phone - because a bar drawn over
 * the companion permanently would be the second thing on a screen whose point is that there is
 * one.
 *
 * The three colours are literals, not tokens, and that is trap 5 read the right way round: this
 * floats over whatever the page behind it happens to be, including a Punggol photograph on
 * /play/ that the theme knows nothing about. It carries its own dark plate and commits to one
 * look, exactly as the play chrome does. Green, amber and red are measured against that plate:
 * 6.5:1, 9.4:1 and 4.9:1. */
.ks-pet__energy{position:absolute;left:50%;bottom:calc(112px * var(--ks-pet-scale) + 6px);transform:translateX(-50%);display:flex;align-items:center;gap:7px;padding:5px 9px;border-radius:999px;background:rgba(9,14,18,.82);box-shadow:0 6px 16px rgba(40,24,8,.34);pointer-events:none;white-space:nowrap}
.ks-pet__energy[hidden]{display:none}
.ks-pet__energy-track{width:64px;height:8px;border-radius:999px;background:rgba(255,253,247,.24);overflow:hidden}
/* Width is the only thing that animates. The colour steps, because 40% is a threshold the
   resident is meant to notice and a gradient through it would hide the moment it crossed. */
.ks-pet__energy-fill{display:block;height:100%;border-radius:999px;background:#57C46A;transition:width 420ms ease}
.ks-pet__energy-value{color:#fff;font:700 12px/1 'Cabin',Verdana,sans-serif;font-variant-numeric:tabular-nums}
.ks-pet__energy[data-level="warn"] .ks-pet__energy-fill{background:#F2C14E}
.ks-pet__energy[data-level="low"] .ks-pet__energy-fill{background:#E4573D}
.ks-pet__energy[data-level="warn"] .ks-pet__energy-value{color:#F7D98A}
.ks-pet__energy[data-level="low"] .ks-pet__energy-value{color:#F6A797}
/* An empty track would read as a bar that failed to load rather than as a pet with nothing
   left, so zero keeps a sliver. */
.ks-pet__energy-fill[style*="width: 0%"]{width:4px !important}
@media (prefers-reduced-motion:reduce){.ks-pet__energy-fill{transition:none}}
