/* ============================================================================
   TACTILE — things in the room you can actually put your hand on.
   Props, dishes, wardrobe pieces, the cloth, the ball. Two layers: one behind
   the character, one in front, so a plate can be held up and a discarded dress
   can lie on the floor behind her.
   ============================================================================ */

.tact-layer { position: absolute; inset: 0; pointer-events: none; overflow: visible; }
.tact-back  { z-index: 1; }
.tact-front { z-index: 6; }
.tact-layer > * { pointer-events: auto; }

.tprop {
  position: absolute; width: var(--w, 18%);
  transform: translate(-50%, -50%) rotate(var(--tilt, 0deg)) scale(var(--sc, 1));
  transition: left 300ms cubic-bezier(.2,.8,.3,1), top 300ms cubic-bezier(.2,.8,.3,1),
              opacity 300ms ease, transform 260ms cubic-bezier(.2,1.4,.4,1);
  touch-action: none; -webkit-user-select: none; user-select: none;
  cursor: pointer; will-change: transform, left, top;
  filter: drop-shadow(0 6px 10px rgba(0,0,0,.5));
}
.tprop svg { width: 100%; height: auto; display: block; overflow: visible; }
/* a generous invisible target: thumbs are not styluses */
.tprop::after { content: ''; position: absolute; inset: -14px; border-radius: 24px; }
.tprop.is-held { transition: none; cursor: grabbing; filter: drop-shadow(0 14px 18px rgba(0,0,0,.6)) brightness(1.08); }
.tprop.is-gone { opacity: 0; transform: translate(-50%, -30%) scale(.86); }
.tprop.is-popped { animation: tpPop 460ms cubic-bezier(.2,1.4,.3,1) forwards; }
@keyframes tpPop {
  0%   { opacity: 1; transform: translate(-50%,-50%) scale(1) }
  40%  { opacity: 1; transform: translate(-50%,-58%) scale(1.24) }
  100% { opacity: 0; transform: translate(-50%,-70%) scale(.5) }
}

.tact-scrim { position: absolute; inset: 0; touch-action: none; }

.tact-cue {
  position: absolute; transform: translate(-50%,-50%);
  font: 400 9.5px/1 'DotGothic16', monospace; letter-spacing: .18em; text-transform: uppercase;
  color: rgba(255,255,255,.72); text-shadow: 0 2px 6px rgba(0,0,0,.9);
  padding: 5px 9px; border-radius: 20px; background: rgba(0,0,0,.34);
  border: 1px solid rgba(255,255,255,.16); pointer-events: none; white-space: nowrap;
  animation: cueIn 260ms ease both, cueOut 420ms ease 1.05s both;
  /* the director shifts cues with a margin, because the transform belongs to
     the animation and the two would fight over it */
  margin-top: var(--cy, 0px);
}
@keyframes cueIn  { from { opacity: 0; transform: translate(-50%,-30%) } }
@keyframes cueOut { to   { opacity: 0; transform: translate(-50%,-90%) } }

.tact-ripple {
  position: absolute; width: 34px; height: 34px; margin: -17px 0 0 -17px;
  border-radius: 50%; border: 2px solid rgba(255,255,255,.7); pointer-events: none;
  animation: tRip 600ms cubic-bezier(.2,.8,.3,1) forwards;
}
@keyframes tRip { from { transform: scale(.2); opacity: .9 } to { transform: scale(1.9); opacity: 0 } }

.tact-speck {
  position: absolute; transform: translate(-50%,-50%); pointer-events: none;
  line-height: 1; text-shadow: 0 1px 3px rgba(0,0,0,.7); will-change: transform, opacity;
}

/* ============================================================
   FOOD
   ============================================================ */
.tprop.food { filter: drop-shadow(0 8px 14px rgba(0,0,0,.6)); }
.fd-steam path {
  fill: none; stroke: #fff; stroke-width: 3; stroke-linecap: round; opacity: .3;
  stroke-dasharray: 44; animation: fdSteam 2.6s ease-in-out infinite;
}
.fd-steam path:nth-child(2) { animation-delay: -.9s } .fd-steam path:nth-child(3) { animation-delay: -1.7s }
@keyframes fdSteam {
  0%   { opacity: 0; transform: translateY(6px) scaleX(.7) }
  30%  { opacity: .38 }
  100% { opacity: 0; transform: translateY(-16px) scaleX(1.25) }
}
.is-remains .fd-steam, .is-crushed .fd-steam { display: none; }

/* portions leave one at a time */
.fd .fp { transition: opacity 240ms ease, transform 320ms cubic-bezier(.3,1.5,.4,1); transform-origin: center; }
.fd .fp.gone { opacity: 0; transform: translateY(-14px) scale(.4); }
.fd .fd-fill, .fd .fd-top, .fd .fd-liq, .fd .fd-surface { transition: transform 420ms ease, opacity 300ms ease; }
.fd .fd-tool { transition: transform 160ms ease; transform-origin: 76px 40px; }

/* the wrapper coming off — driven by --open, 0..1 */
.food .fd-wrapL { transform: rotate(calc(var(--open, 0) * -74deg)) translateX(calc(var(--open,0) * -8px)); transform-origin: 60px 30px; transition: transform 200ms ease, opacity 300ms; }
.food .fd-wrapR { transform: rotate(calc(var(--open, 0) *  74deg)) translateX(calc(var(--open,0) *  8px)); transform-origin: 60px 30px; transition: transform 200ms ease, opacity 300ms; }
.food.is-open .fd-wrapL, .food.is-open .fd-wrapR { opacity: .55; }
.food.is-crumpled .fd-wrapL, .food.is-crumpled .fd-wrapR { transform: scale(.12) translateY(60px); opacity: 0; transition: transform 340ms cubic-bezier(.4,0,1,1), opacity 340ms; }

/* stirring shows up as the contents turning over */
.food .fd-fill { transform-origin: center; }
.food.is-stirred .fd-fill { filter: saturate(1.25) brightness(1.06); }
.food.is-stringy::before {
  content: ''; position: absolute; left: 46%; top: 6%; width: 8%; height: 46%;
  background: repeating-linear-gradient(180deg, rgba(230,210,150,.85) 0 2px, transparent 2px 6px);
  transform: rotate(6deg); pointer-events: none;
}

/* reactions of the object itself */
.food.is-nibbled { animation: fdNibble 380ms ease; }
@keyframes fdNibble { 0%,100%{transform:translate(-50%,-50%) scale(1)} 40%{transform:translate(-50%,-52%) scale(1.06,.95)} }
.food.is-hit { animation: fdHit 400ms cubic-bezier(.3,1.4,.4,1); }
@keyframes fdHit { 0%,100%{transform:translate(-50%,-50%) scale(1) rotate(0)} 30%{transform:translate(-50%,-46%) scale(1.12,.9) rotate(-4deg)} 60%{transform:translate(-50%,-52%) scale(.95,1.06) rotate(3deg)} }
.food.is-pouring { transform: translate(-50%,-50%) rotate(var(--tilt,0deg)); transition: transform 90ms linear; }
.food.is-crushed { animation: fdCrush 420ms cubic-bezier(.4,0,.6,1) forwards; }
@keyframes fdCrush { to { transform: translate(-50%,-46%) scale(.42, .3) rotate(-12deg); opacity: .8; filter: brightness(.7) } }
.food.is-scanned::before {
  content: ''; position: absolute; inset: -6% -12%; pointer-events: none;
  background: linear-gradient(180deg, transparent 44%, rgba(255,46,63,.85) 50%, transparent 56%);
  animation: fdScan 900ms linear;
}
@keyframes fdScan { from { transform: translateY(-60%) } to { transform: translateY(60%) } }
.food.is-sniffed { animation: fdSniff 800ms ease; }
@keyframes fdSniff { 0%,100%{transform:translate(-50%,-50%)} 25%{transform:translate(-54%,-50%)} 65%{transform:translate(-46%,-50%)} }
.food.is-remains { filter: drop-shadow(0 4px 8px rgba(0,0,0,.45)) saturate(.7); opacity: .9; }
.food.piece { filter: drop-shadow(0 5px 8px rgba(0,0,0,.55)); z-index: 2; }

/* ============================================================
   CLOTH / BRUSH — the thing that follows your finger while caring
   ============================================================ */
.tprop.tool { filter: drop-shadow(0 8px 12px rgba(0,0,0,.55)); z-index: 3; }
.tprop.tool.is-held { transform: translate(-50%,-50%) rotate(var(--tilt,-12deg)) scale(1.06); }

.grime-layer { position: absolute; inset: 0; pointer-events: none; z-index: 5; }
.grime {
  position: absolute; transform: translate(-50%,-50%) rotate(var(--r,0deg));
  width: var(--gw, 12%); height: var(--gh, 7%); border-radius: 50%;
  background: radial-gradient(ellipse at 40% 40%, rgba(90,74,52,.85), rgba(60,48,32,.15) 72%);
  transition: opacity 300ms ease, transform 300ms ease;
}
.grime.wiped { opacity: 0; transform: translate(-50%,-50%) scale(1.5); }
.grime.spark { background: radial-gradient(ellipse at 40% 40%, rgba(255,240,200,.75), rgba(255,220,150,.05) 72%); }

/* the shine that comes off a clean patch */
.care-shine {
  position: absolute; transform: translate(-50%,-50%);
  font-size: 16px; color: #fff8d8; text-shadow: 0 0 10px #ffe9a8; pointer-events: none;
  animation: shineUp 700ms ease-out forwards;
}
@keyframes shineUp { from { opacity: 0; transform: translate(-50%,-40%) scale(.4) } 40% { opacity: 1 } to { opacity: 0; transform: translate(-50%,-90%) scale(1.2) } }

/* ============================================================
   PLAY — the ball, the ribbon, the coin
   ============================================================ */
.tprop.toy { filter: drop-shadow(0 7px 10px rgba(0,0,0,.55)); }
.tprop.toy.is-flying { transition: left 460ms cubic-bezier(.2,.5,.4,1), top 460ms cubic-bezier(.3,.1,.6,1); }
.toy-trail {
  position: absolute; transform: translate(-50%,-50%); width: 8px; height: 8px; border-radius: 50%;
  background: var(--accent, #fff); opacity: .4; pointer-events: none;
  animation: trailFade 460ms ease forwards;
}
@keyframes trailFade { to { opacity: 0; transform: translate(-50%,-50%) scale(.3) } }

/* ============================================================
   ROOM POKES — invisible until touched. No icons anywhere.
   ============================================================ */
.poke-layer { position: absolute; inset: 0; z-index: 5; pointer-events: none; }
.poke-spot {
  position: absolute; transform: translate(-50%,-50%);
  width: var(--pw, 16%); height: var(--ph, 12%); border-radius: 40%;
  pointer-events: auto; cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.poke-spot.hit::after {
  content: ''; position: absolute; inset: 0; border-radius: 40%;
  background: radial-gradient(ellipse at center, rgba(255,255,255,.22), transparent 70%);
  animation: pokeGlow 520ms ease forwards;
}
@keyframes pokeGlow { from { opacity: 1; transform: scale(.7) } to { opacity: 0; transform: scale(1.3) } }

/* things in the room reacting to being touched */
.sc-moon.poked   { animation: moonWobble 900ms cubic-bezier(.2,1.4,.3,1); }
@keyframes moonWobble { 0%,100%{transform:scale(1)} 30%{transform:scale(1.12) translateY(-4px)} 60%{transform:scale(.96)} }
.neon.poked      { animation: neonZap 620ms steps(2) 2; }
@keyframes neonZap { 0%,100%{opacity:1} 50%{opacity:.15} }
.lantern.poked   { animation: lanternSwing 1.4s cubic-bezier(.3,.8,.4,1); transform-origin: 50% 0; }
@keyframes lanternSwing { 0%{transform:rotate(0)} 25%{transform:rotate(13deg)} 55%{transform:rotate(-9deg)} 80%{transform:rotate(4deg)} 100%{transform:rotate(0)} }
.sc-torii.poked  { animation: toriiRing 1.1s ease; }
@keyframes toriiRing { 0%,100%{filter:none} 25%{filter:drop-shadow(0 0 14px rgba(255,180,90,.9))} }
.sc-pipes.poked  { animation: pipeClank 520ms ease; }
@keyframes pipeClank { 0%,100%{transform:translateX(0)} 25%{transform:translateX(-3px)} 60%{transform:translateX(2px)} }
.sc-puddle.poked { animation: puddleRipple 1s ease; }
@keyframes puddleRipple { 0%,100%{transform:scaleX(1)} 40%{transform:scaleX(1.06) scaleY(.94)} }
.sc-city.poked .sc-win rect { animation: winFlick 900ms steps(3); }
@keyframes winFlick { 0%,100%{opacity:1} 40%{opacity:.2} 70%{opacity:1} }

/* ============================================================
   AFTERMATH — what an event leaves lying around
   ============================================================ */
.residue-layer { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
.residue {
  position: absolute; transform: translate(-50%,-50%) rotate(var(--r,0deg));
  font-size: var(--fs, 22px); line-height: 1; pointer-events: auto; cursor: pointer;
  filter: drop-shadow(0 3px 6px rgba(0,0,0,.65));
  animation: resIn 520ms cubic-bezier(.2,1.5,.4,1) both;
}
.residue::after { content: ''; position: absolute; inset: -12px; }
.residue.fading { animation: resOut 900ms ease forwards; }
@keyframes resIn  { from { opacity: 0; transform: translate(-50%,-120%) rotate(-50deg) } }
@keyframes resOut { to { opacity: 0; transform: translate(-50%,-50%) rotate(var(--r,0deg)) scale(.5) } }
.residue.crooked { animation: resIn 520ms cubic-bezier(.2,1.5,.4,1) both, resWobble 3.6s ease-in-out 520ms infinite; }
@keyframes resWobble { 0%,100%{transform:translate(-50%,-50%) rotate(var(--r,0deg))} 50%{transform:translate(-50%,-50%) rotate(calc(var(--r,0deg) + 5deg))} }

/* stuck-on state the character wears for a while after something happened */
.chr.is-bandaged .head-group::after { content: ''; }
.creature-wrap.aft-bandage::before {
  content: '🩹'; position: absolute; left: 58%; top: 20%; font-size: 20px; z-index: 3;
  transform: rotate(18deg); filter: drop-shadow(0 2px 4px rgba(0,0,0,.6));
  animation: resIn 520ms cubic-bezier(.2,1.5,.4,1) both;
}
.creature-wrap.aft-sulk .creature { transform: translateY(6px) scale(.97); filter: saturate(.85); }
.creature-wrap.aft-hungover .creature { filter: saturate(.7) hue-rotate(-14deg) brightness(.92); animation: hungSway 4.6s ease-in-out infinite; }
@keyframes hungSway { 0%,100%{transform:rotate(-1.6deg)} 50%{transform:rotate(1.6deg)} }
.creature-wrap.aft-soaked .creature { filter: brightness(.9) saturate(1.15); }
.creature-wrap { transition: transform 600ms ease; }

/* ============================================================
   WEATHER / LIGHT the events can change
   ============================================================ */
.stage.wx-dark   { filter: brightness(.28) saturate(.55); transition: filter 700ms ease; }
.stage.wx-flash  { filter: brightness(2.1) saturate(.8); transition: filter 90ms ease; }
.stage { transition: filter 900ms ease; }

.snow-cap {
  position: absolute; left: 0; right: 0; pointer-events: none; z-index: 1;
  height: 4px; background: linear-gradient(180deg, rgba(255,255,255,.9), rgba(255,255,255,0));
  opacity: 0; transition: opacity 2.4s ease;
}
.stage.has-snow .snow-cap { opacity: .85; }
.stage.has-snow .sc-floor::after {
  content: ''; position: absolute; left: 0; right: 0; top: 0; height: 6px;
  background: linear-gradient(180deg, rgba(255,255,255,.55), transparent);
}

@media (prefers-reduced-motion: reduce) {
  .tprop, .tprop.toy.is-flying { transition-duration: 1ms !important; }
  .fd-steam path, .residue.crooked { animation: none; }
}

/* ============================================================
   IDLE — the character actually moving about her own room
   ============================================================ */
.creature-wrap { transition: transform 700ms cubic-bezier(.3,.9,.3,1); }
.creature-wrap.idle-lean-l  { transform: translateX(calc(-50% - 5%)) rotate(-3deg); }
.creature-wrap.idle-lean-r  { transform: translateX(calc(-50% + 5%)) rotate(3deg); }
.creature-wrap.idle-left    { transform: translateX(calc(-50% - 22%)) scale(.94); }
.creature-wrap.idle-right   { transform: translateX(calc(-50% + 22%)) scale(.94); }
.creature-wrap.idle-window  { transform: translateX(calc(-50% - 26%)) translateY(-4%) scale(.9); }
.creature-wrap.idle-low     { transform: translateX(-50%) translateY(7%) scale(.95, .9); }
.creature-wrap.idle-tall    { transform: translateX(-50%) translateY(-4%) scale(1.03, 1.05); }
.tprop.idle-prop { filter: drop-shadow(0 6px 9px rgba(0,0,0,.55)); z-index: 2; }

/* cheeks full of food */
.chr.is-stuffed .rig { animation: chew 900ms ease-in-out; }
@keyframes chew { 0%,100%{transform:scale(1)} 25%{transform:scale(1.05,.96)} 55%{transform:scale(.98,1.03)} 80%{transform:scale(1.03,.98)} }
.chr.is-stuffed .cheek { opacity: 1 !important; transform: scale(1.35); transform-origin: center; transition: transform 200ms ease; }

/* What she is wearing. It lives inside .rig, so every transform that moves her
   moves it too — no positioning needed here, only the little arrival pop. */
.creature { position: relative; }
.chr.s-transformed .outfit-layer { display: none; }
.outfit-layer > g { animation: ofOn 420ms cubic-bezier(.2,1.5,.4,1) both; transform-origin: center; transform-box: fill-box; }
@keyframes ofOn { from { opacity: 0; transform: translateY(-10px) scale(.86) } }

/* ============================================================
   WARDROBE — the rail, in the same room she is standing in
   ============================================================ */
.wardrobe {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 9;
  background: linear-gradient(180deg, rgba(20,12,30,.0), rgba(18,10,28,.93) 26%);
  padding: 16px 10px calc(6px + env(safe-area-inset-bottom, 0px));
  transform: translateY(102%); transition: transform 320ms cubic-bezier(.2,.9,.3,1);
}
.wardrobe.is-in { transform: none; }
/* the rail takes the bottom third, so what she is saying moves up out of it.
   The class is set from JS; :has() is the same rule for browsers that have it
   and does no harm on the ones that do not. */
.stage.is-styling .bubble-wrap,
.stage:has(.wardrobe.is-in) .bubble-wrap { bottom: 52%; }
.wr-head { display: flex; align-items: center; gap: 8px; padding: 0 4px 7px; }
.wr-kanji { font: 800 15px/1 'Shippori Mincho B1', serif; color: var(--accent, #ffa8d8); }
.wr-title { flex: 1; font: 400 10px/1.2 'DotGothic16', monospace; letter-spacing: .2em; color: #fff; opacity: .85; }
.wr-title small { display: block; font-size: 7.5px; letter-spacing: .1em; opacity: .5; margin-top: 3px; text-transform: uppercase; }
.wr-x {
  width: 30px; height: 30px; border-radius: 9px; border: 1px solid rgba(255,255,255,.18);
  background: rgba(255,255,255,.06); color: #fff; font-size: 13px; cursor: pointer;
}
.wr-rail {
  display: flex; gap: 8px; overflow-x: auto; overflow-y: hidden;
  padding: 3px 2px 5px; scroll-snap-type: x proximity; -webkit-overflow-scrolling: touch;
}
.wr-rail::-webkit-scrollbar { height: 3px; }
.wr-rail::-webkit-scrollbar-thumb { background: rgba(255,255,255,.2); border-radius: 3px; }
.wr-item {
  flex: 0 0 auto; width: 68px; padding: 6px 4px 5px; scroll-snap-align: center;
  background: rgba(255,255,255,.055); border: 1px solid rgba(255,255,255,.13); border-radius: 13px;
  display: grid; gap: 4px; justify-items: center; cursor: grab;
  touch-action: none; -webkit-tap-highlight-color: transparent;
  transition: transform 160ms ease, border-color 160ms ease, background 160ms ease;
}
.wr-item:active { transform: scale(.94); cursor: grabbing; }
.wr-item.is-worn { border-color: var(--accent, #ffa8d8); background: rgba(255,168,216,.14); }
.wr-art { width: 38px; height: 38px; display: block; pointer-events: none; }
.wr-name { font: 500 8.5px/1.15 'Chakra Petch', sans-serif; letter-spacing: .04em; color: #fff; opacity: .8; text-align: center; }
.tprop.wr-ghost { z-index: 12; filter: drop-shadow(0 12px 16px rgba(0,0,0,.65)); }
.tprop.wr-drop { opacity: .92; filter: drop-shadow(0 4px 7px rgba(0,0,0,.5)) saturate(.9); }
.tprop.mirror { cursor: pointer; }
.tprop.mirror.is-checked { animation: mirrorShine 900ms ease; }
@keyframes mirrorShine { 0%,100%{filter:drop-shadow(0 6px 10px rgba(0,0,0,.5))} 40%{filter:drop-shadow(0 0 18px rgba(255,235,200,.9)) brightness(1.25)} }

/* ============================================================
   IN-ROOM EVENT PROPS
   ============================================================ */
.pz { font-size: 34px; line-height: 1; text-align: center; filter: drop-shadow(0 4px 7px rgba(0,0,0,.6)); }
.tprop.crane { z-index: 8; transition: none; }
.tprop.crane .cl-arm { transition: transform 300ms ease; transform-origin: 30px 42px; }
.tprop.crane.is-down .cl-arm { transform: scaleX(.55); }
.tprop.prize .pz { font-size: 30px; }
.tprop.door .dr-crack { transition: width 400ms ease; }
.tprop.leak .drip { animation: dripPulse 1.4s ease-in-out infinite; }
@keyframes dripPulse { 0%,100%{transform:translateY(0) scale(1)} 50%{transform:translateY(4px) scale(1.1)} }
.tprop.searchspot { opacity: .55; }
.tprop.searchspot:active { opacity: .9; }
.creature-wrap.is-wobbling { animation: wobbleOver 900ms ease-in-out infinite; }
@keyframes wobbleOver {
  0%,100% { transform: translateX(-50%) rotate(-7deg) }
  50%     { transform: translateX(-50%) rotate(8deg) }
}

/* snow, when an event brings it */
.wx-snow {
  position: absolute; width: 8px; height: 8px; border-radius: 50%;
  background: #f2f8ff; box-shadow: 0 0 6px rgba(230,242,255,.9);
}

@media (prefers-reduced-motion: reduce) {
  .creature-wrap { transition-duration: 1ms; }
  .creature-wrap.is-wobbling { animation: none; }
}

/* the claw machine */
.tprop.cranebox { opacity: .95; }
.tprop.crane { z-index: 8; }

/* what did not make it into the mouth */
.spill {
  position: absolute; transform: translate(-50%,-50%);
  width: var(--sw, 10px); height: calc(var(--sw, 10px) * .5);
  border-radius: 50%; opacity: .55; pointer-events: none;
  filter: blur(.4px); animation: resIn 400ms ease both;
}
.spill.fading { animation: resOut 800ms ease forwards; }
.creature-wrap.aft-sauce::after {
  content: ''; position: absolute; left: 57.5%; top: 30%;
  width: 11px; height: 7px; border-radius: 50%;
  background: var(--sauce, #e8d3ac); opacity: .8; z-index: 3;
  transform: rotate(-12deg);
  animation: resIn 320ms cubic-bezier(.2,1.5,.4,1) both;
}

/* ============================================================
   SCHLAFEN — die Decke wird hochgezogen, nicht hingestellt
   ============================================================ */
.blanket {
  position: absolute; left: -2%; right: -2%; bottom: 0; height: 40%;
  z-index: 3; pointer-events: none; touch-action: none;
  transform: translateY(102%);
  transition: transform 900ms cubic-bezier(.25,.9,.3,1);
  filter: drop-shadow(0 -6px 14px rgba(0,0,0,.45));
}
.blanket svg { width: 100%; height: 100%; display: block; }
.blanket .bl-body { fill: var(--blanketInk, #6a4f9e); }
.blanket .bl-fold { fill: #fff; opacity: .16; }
.blanket.is-up   { transform: translateY(46%); }
.blanket.is-snug { transform: translateY(22%); }
/* greifbar, solange sie schlaeft (render setzt das) — wach liegt sie unten und
   faengt keine Klicks fuer den Boden ab */
.blanket.is-grabbable { pointer-events: auto; cursor: grab; }
/* die Kante ist wellig und schmal: ein unsichtbarer Streifen darueber, damit
   der Finger nicht knapp daneben auf ihr landet */
.blanket.is-grabbable::before { content: ''; position: absolute; left: 0; right: 0; top: -26px; height: 26px; }
.blanket.is-held { cursor: grabbing; filter: drop-shadow(0 -8px 16px rgba(0,0,0,.5)) brightness(1.06); }
.theme-moon   { --blanketInk: #6a4f9e; }
.theme-dragon { --blanketInk: #2a2f38; }
.theme-goro   { --blanketInk: #4a3a26; }

/* sie sackt beim Zugedecktwerden ein Stueck zusammen */
.creature-wrap.is-settling { transform: translateX(-50%) translateY(2.5%) scale(.985); }

/* ============================================================
   BUERSTEN — es muss sich anfuehlen, nicht nur zaehlen
   ============================================================ */
/* das Haar geht mit dem Strich mit */
.chr.is-brushed .twintail { animation: hairStroke 760ms cubic-bezier(.3,.8,.4,1); }
.chr.is-brushed .twintail.tr { animation-delay: 70ms; }
@keyframes hairStroke {
  0%   { transform: rotate(-3deg) scaleY(1) }
  35%  { transform: rotate(4deg) scaleY(1.035) }
  70%  { transform: rotate(-2deg) scaleY(.99) }
  100% { transform: rotate(-3deg) scaleY(1) }
}
.chr.is-brushed .p-normal { filter: brightness(1.04); }

/* die Spur, die die Buerste zieht */
.brush-trail {
  position: absolute; transform: translate(-50%,-50%) rotate(var(--r, 0deg));
  width: 26px; height: 3px; border-radius: 3px; pointer-events: none;
  background: linear-gradient(90deg, transparent, #fff6d8, transparent);
  animation: trailGo 520ms ease-out forwards;
}
@keyframes trailGo {
  from { opacity: .85; transform: translate(-50%,-50%) rotate(var(--r,0deg)) scaleX(.4) }
  to   { opacity: 0;   transform: translate(-50%,-50%) rotate(var(--r,0deg)) scaleX(1.5) }
}

/* die Knoten sehen aus wie Knoten, nicht wie Flecken */
/* ein Knoten im Haar, kein Fleck und keine Seifenblase: ein paar verhedderte
   Straehnen in ihrer eigenen Haarfarbe, dunkler als das Haar drumherum */
.grime.tangle {
  background:
    repeating-conic-gradient(from 0deg at 50% 50%,
      rgba(150,105,25,.9) 0deg 22deg, rgba(214,164,60,.55) 22deg 46deg) !important;
  border-radius: 46% 54% 38% 62%;
  box-shadow: inset 0 0 4px rgba(90,60,10,.6), 0 1px 3px rgba(0,0,0,.35);
  animation: tangleTwist 2.6s ease-in-out infinite;
}
@keyframes tangleTwist { 0%,100%{transform:translate(-50%,-50%) rotate(var(--r,0deg))} 50%{transform:translate(-50%,-50%) rotate(calc(var(--r,0deg) + 12deg)) scale(1.05)} }
.grime.fault {
  background: none !important;
  border: 2px dashed rgba(255,70,80,.85); border-radius: 30%;
  animation: faultBlink .7s steps(2) infinite;
}
@keyframes faultBlink { 0%,100%{opacity:1} 50%{opacity:.45} }

@media (prefers-reduced-motion: reduce) {
  .blanket { transition-duration: 1ms; }
  .chr.is-brushed .twintail, .grime.tangle, .grime.fault { animation: none; }
}
