/* melt.css - the melt ceremony and the receipt that follows it.
   Pairs with public/js/melt.js the way locker.css pairs with locker.js. Split out
   of locker.css because it is a different subject: the locker is a panel you
   browse, this is a destructive modal flow with its own ladder of confirmations,
   and locker.css had no room left for the locker's own layout. Moved verbatim.
   `--melt-rar` is set on the element by melt.js and carries the tier through the
   edge, the character chips, the hold fill and the armed button. */

/* ---- The melt ceremony ---------------------------------------------------
   Melting is permanent, so the register is serious rather than playful: weight, not
   scolding. `--melt-rar` is set on the element by melt.js and carries the tier through
   the edge, the character chips, the hold fill and the armed button, so each part
   takes one rule instead of one rule per rarity. */
.melt-modal {
  position: fixed; inset: 0; z-index: 60; padding: 20px; display: grid; place-items: center;
  background: rgba(4,6,16,.74); animation: meltFade var(--t-base) var(--e-standard);
  -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px); }
@keyframes meltFade { from { opacity: 0; } to { opacity: 1; } }
.melt-box {
  position: relative; width: min(460px, 100%); padding: 20px; border-radius: 16px;
  background: linear-gradient(180deg, #171c38, #10142a); box-shadow: 0 24px 60px rgba(0,0,0,.55);
  border: 1px solid rgba(255,255,255,.14); animation: meltRise var(--t-expressive) var(--e-enter); }
/* The tier, readable before a word of the dialog is: the same colour language the
   commit button already speaks, on the edge where it cannot be missed. */
.melt-box::before {
  content: ""; position: absolute; inset: 0 0 auto; height: 3px; border-radius: 16px 16px 0 0;
  background: linear-gradient(90deg, transparent, var(--melt-rar, #f5b301), transparent); }
@keyframes meltRise { from { opacity: 0; transform: translateY(10px) scale(.985); } to { opacity: 1; transform: none; } }
.melt-box h3 { margin: 0 0 12px; font-size: 1.12rem; line-height: 1.25; }

/* What goes and what comes back, side by side. The old dialog buried the payout in a
   sentence, and that number is the one people actually decide on. */
.melt-ledger {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 10px 12px; border-radius: 10px; background: rgba(255,255,255,.045);
  border: 1px solid rgba(255,255,255,.09); }
.ml-what, .ml-pay { display: flex; flex-direction: column; gap: 3px; font-weight: 700; }
.ml-pay { text-align: right; color: #ffe08a; font-variant-numeric: tabular-nums; }
.ml-what i, .ml-pay i { font-style: normal; font-size: .68rem; font-weight: 600;
  letter-spacing: .05em; text-transform: uppercase; color: #b9c4e6; }
.melt-perm { margin: 10px 0 0; font-size: .82rem; color: #c3cbe6; }
.melt-disclaimer {
  border-left: 3px solid #2ec26b; background: rgba(46,194,107,.10);
  padding: 10px 12px; border-radius: 0 8px 8px 0; font-size: .9rem; }

/* The typing gate: one chip per character, each lighting as it lands. The field used
   to give no sign it was being read, so a wrong third letter looked exactly like a
   right one until the button failed to enable. */
.melt-typebox { margin: 12px 0; }
.melt-type { display: block; font-size: .9rem; margin-bottom: 8px; }
.melt-ghost { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 8px; }
.mg-ch {
  min-width: 22px; padding: 3px 0; text-align: center; border-radius: 6px;
  font-weight: 800; font-size: .9rem; letter-spacing: .04em; color: #97a2c4;
  border: 1px solid rgba(255,255,255,.16); background: rgba(255,255,255,.03);
  transition: color var(--t-quick) var(--e-standard), background var(--t-quick) var(--e-standard), border-color var(--t-quick) var(--e-standard); }
.mg-ch.mg-space { min-width: 10px; border-color: transparent; background: none; }
.mg-ch.on { color: #0b0f04; background: var(--melt-rar, #f5b301); border-color: transparent; }
/* The character you are on. A steady border, never a blink: nothing here flashes. */
.mg-ch.next { border-color: var(--melt-rar, #f5b301); color: #eaf1ff; }
.mg-ch.just { animation: mgTick var(--t-base) var(--e-snap); }
@keyframes mgTick { 40% { transform: scale(1.18); } to { transform: scale(1); } }
.melt-typebox input {
  width: 100%; min-height: 44px; padding: 11px 12px; border-radius: 8px;
  border: 1px solid rgba(255,255,255,.2); background: rgba(0,0,0,.32); color: inherit;
  font: inherit; font-weight: 700; letter-spacing: .06em;
  transition: border-color var(--t-quick) var(--e-standard); }
/* Not a shake and not a red flash. A mistyped character simply does not light and the
   field says so once, quietly. Melting is destructive, not shameful. */
.melt-box.mistyped .melt-typebox input { border-color: rgba(255,164,164,.55); }
.melt-type-state { margin: 6px 0 0; min-height: 1.1em; font-size: .78rem; color: #ffd7a1; }

.melt-optout { /* 44px, like everything else you can tap */
  display: flex; gap: 10px; align-items: center; min-height: 44px;
  font-size: .85rem; color: #c3cbe6; margin: 2px 0; }
.melt-optout input { flex: 0 0 auto; width: 18px; height: 18px; }
.melt-actions { display: flex; gap: 10px; justify-content: flex-end; margin-top: 14px; }
/* The commitment beat, which none of these had: ui.css's shared :active list does not
   cover the melt controls, so a press on the most consequential button in the game
   used to do nothing at all until the result came back. */
.melt-bar-btn:active:not(:disabled), .melt-bar-clear:active, .melt-cancel:active,
.melt-go:active:not(:disabled), .mr-x:active { transform: scale(.965); transition-duration: var(--t-instant); }
/* The instant the phrase matches. One pulse, not a loop. */
.melt-go.armed { animation: meltArm var(--t-expressive) var(--e-snap); }
@keyframes meltArm {
  from { transform: scale(1); box-shadow: 0 0 0 0 var(--melt-rar, #f5b301); }
  60% { transform: scale(1.04); } to { transform: scale(1); box-shadow: 0 0 0 12px transparent; } }

/* The three-second change-your-mind bar. Green only, never skippable. The number is
   time LEFT and the sweep runs off the same clock, so both are the truth. It used to
   be a bar labelled "Melting…" while nothing was being melted. */
.melt-hold { margin-top: 14px; }
.melt-box.holding .melt-typebox, .melt-box.holding .melt-optout { display: none; }
.mh-top {
  display: flex; align-items: baseline; justify-content: space-between;
  font-size: .78rem; letter-spacing: .06em; text-transform: uppercase; color: #c3cbe6; }
.mh-secs {
  font-size: 1.6rem; font-weight: 800; line-height: 1;
  font-variant-numeric: tabular-nums; color: var(--melt-rar, #2ec26b); }
.mh-track {
  height: 8px; margin-top: 6px; border-radius: 999px; overflow: hidden;
  background: rgba(255,255,255,.13); border: 1px solid rgba(255,255,255,.10); }
/* scaleX, driven by melt.js off the elapsed clock. Never width: that is layout. */
.mh-fill {
  display: block; height: 100%; width: 100%; background: var(--melt-rar, #2ec26b);
  transform: scaleX(0); transform-origin: left center; }
.mh-hint { margin: 8px 0 0; font-size: .8rem; color: #c3cbe6; }

/* ---- The melt receipt ----------------------------------------------------
   The payoff. Destroying a skin used to end in a 13px grey sentence under the Titles
   section that a screen reader never announced and nothing ever cleared, and on the
   tiers with no ceremony it ended in nothing at all. Anchored rather than centred, and
   NOT modal: it reports on the Locker, so it must neither cover it nor interrupt a
   player who is still working. */
.melt-receipt {
  position: fixed; z-index: 62; left: 50%; bottom: 14px; transform: translateX(-50%);
  width: min(370px, calc(100vw - 20px)); animation: mrIn var(--t-base) var(--e-enter); }
@keyframes mrIn { from { opacity: 0; transform: translate(-50%, 12px); } to { opacity: 1; transform: translate(-50%, 0); } }
.melt-receipt.leaving { animation: mrOut var(--t-quick) var(--e-exit) forwards; }
@keyframes mrOut { to { opacity: 0; transform: translate(-50%, 6px); } }
.mr-box {
  border-radius: 12px; padding: 12px 14px; box-shadow: 0 18px 40px rgba(0,0,0,.5);
  background: linear-gradient(180deg, #191e3c, #11152b); border: 1px solid rgba(255,255,255,.14);
  border-left: 3px solid var(--melt-rar, #f5b301); }
.mr-head { display: flex; align-items: center; gap: 9px; }
.mr-title { flex: 1; font-size: .95rem; }
.mr-mark { flex: 0 0 auto; width: 10px; height: 10px; border-radius: 50%; background: var(--melt-rar, #f5b301); }
/* In flight is the only state that moves, and it moves at 0.6 Hz. */
.melt-receipt.working .mr-mark { animation: mrPulse 1.7s var(--e-standard) infinite; }
@keyframes mrPulse { 0%, 100% { opacity: .3; } 50% { opacity: 1; } }
.mr-x { /* a small glyph inside a 44px target, same as the pager arrows */
  flex: 0 0 auto; width: 44px; height: 44px; margin: -12px -12px -12px 0; cursor: pointer;
  background: none; border: 0; border-radius: 10px; color: #9aa3c7; font: inherit; font-size: 1.2rem; }
.mr-x:hover { color: #fff; background: rgba(255,255,255,.08); }
.mr-list { list-style: none; margin: 8px 0 0; padding: 0; }
.mr-row { display: flex; align-items: center; gap: 8px; padding: 2px 0; font-size: .84rem; }
.mr-dot { flex: 0 0 auto; width: 8px; height: 8px; border-radius: 50%; }
.mr-name { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mr-n, .mr-gems { font-variant-numeric: tabular-nums; color: #c3cbe6; }
.mr-more { color: #9aa3c7; font-size: .8rem; }
/* The number the whole thing exists to deliver. It counts up from 0 rather than just
   appearing, because the point is to watch the Gems land. */
.mr-payout {
  margin-top: 8px; font-size: 1.5rem; line-height: 1.1; font-weight: 800; color: #ffe08a;
  font-variant-numeric: tabular-nums;
}
.melt-receipt.working .mr-payout { opacity: .3; } /* nothing has been paid yet */
.mr-sub { margin: 4px 0 0; font-size: .8rem; color: #c3cbe6; }
.melt-receipt.failed .mr-box { border-left-color: #ff6b7f; }
.melt-receipt.failed .mr-gems { display: none; } /* nothing was paid, so quote nothing */

/* Reduced motion: intensity only. The hold's sweep and countdown are driven by JS and
   stay exactly as they are, because they are the only signal of how long is left. */
@media (prefers-reduced-motion: reduce) {
  .melt-box, .melt-receipt { animation-name: meltFade; animation-duration: var(--t-base); }
  .melt-receipt.leaving { animation: none; opacity: 0; }
  .mg-ch.just, .melt-go.armed { animation: none; }
  .melt-receipt.working .mr-mark { animation: none; opacity: .8; }
}

/* Short viewports. This dialog can be carrying a prestige note AND the green
   disclaimer, and nothing here scrolls, so it is made to fit rather than allowed to
   spill: measured at 462px inside the 528px a 320x568 phone leaves it. */
@media (max-height: 640px) {
  .melt-modal { padding: 10px; }
  .melt-box { padding: 14px; border-radius: 12px; }
  .melt-box h3 { margin-bottom: 8px; font-size: 1rem; }
  .melt-ledger { padding: 7px 10px; }
  .melt-disclaimer, .melt-perm, .melt-note, .mh-hint { font-size: .78rem; }
  .melt-disclaimer { padding: 7px 10px; } .melt-typebox, .melt-perm { margin: 8px 0 0; }
  .melt-actions, .melt-hold { margin-top: 10px; } .mh-secs { font-size: 1.25rem; }
}
/* Landscape: the dialog gets about 340px, and a green prestige melt measured 419px here
   with its buttons off the bottom edge. The chips go (the field still shows what you
   typed); the permanence line goes only where the disclaimer already repeats it. */
@media (max-height: 460px) {
  .melt-box { padding: 10px; } .melt-box h3 { font-size: .95rem; } .melt-ghost { display: none; }
  .melt-box:has(.melt-disclaimer) .melt-perm { display: none; } .melt-note { padding: 5px 10px; }
  .melt-disclaimer { font-size: .74rem; padding: 5px 9px; } .melt-ledger { padding: 4px 10px; }
  .melt-optout { margin: 0; } .melt-type { margin: 0 0 4px; } .melt-typebox { margin: 6px 0 0; } .melt-actions { margin-top: 8px; }
}

/* A card whose stats are open is not the same as one that has focus: without this the
   resting outline outranks the shared ring in ui.css and the keyboard loses its place. */
.skin-card.locker-open:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
