/* Storage bin (js/ui/storageBin.js): the crate is a physical container. Stored items are absolutely placed bodies
   driven by transform (translate + tumble rotate + spawn scale); they fall in over the rim, pile up and rest.
   No flex flow, no scroll: a stuffed crate gets denser (smaller bin cell) and the pile can rise over the rim. */
.storage.crate { display: block; overflow: visible; z-index: 6; }
.storage.crate .bin-layer { position: absolute; inset: 0; pointer-events: none; z-index: 2; }
.storage.crate .bin-layer .piece { position: absolute; left: 0; top: 0; margin: 0; transform-origin: 50% 50%;
  animation: none !important; transition: none; will-change: transform; filter: drop-shadow(0 4px 3px rgba(0,0,0,.6)); }
.storage.crate .bin-layer .piece .cell { pointer-events: auto; cursor: grab; }
.storage.crate .crate-label, .storage.crate .crate-hint { z-index: 1; }
/* the STORAGE stamp is a small plaque on the crate's top rim, under the bin layer: a pile rising over the rim covers it,
   it never covers an item. The overflow hint sits just below it inside the crate. */
.storage.crate .crate-label { top: -9px; bottom: auto; left: 50%; right: auto; transform: translateX(-50%); padding: 1px 10px 2px;
  font-size: 11px; letter-spacing: .2em; line-height: 14px; color: rgba(240,210,150,.8); border-radius: 2px;
  background: linear-gradient(#5a381c, #3e2610); box-shadow: inset 0 0 0 1px rgba(0,0,0,.7), 0 1px 2px rgba(0,0,0,.6); }
.storage.crate .crate-hint { top: 10px; }
.storage.crate .crate-hint[hidden] { display: none; }

/* a buy you cannot afford springs back to the shelf; its price tag shakes (no toast) */
.tag.shake { animation: tag-shake .38s cubic-bezier(.36,.07,.19,.97); }
@keyframes tag-shake {
  15%, 85% { transform: translateX(-2px); } 30%, 70% { transform: translateX(4px) rotate(2deg); }
  45%, 55% { transform: translateX(-5px) rotate(-2deg); }
}
@media (prefers-reduced-motion: reduce) { .tag.shake { animation: none; outline: 2px solid #c0281c; } }
