/* ═══════════════════════════════════════════════════════════════════════
   Blood & Nectar — The forge ceremony  (/game/loot.html)
   ---------------------------------------------------------------------
   Mixing a Mystery Flask used to be a POST and a sentence. This turns the
   ring that was already sitting in .lt-stage into the thing that actually
   performs the craft: energy arcs spin up around a gold bezel, three arms
   lock the inputs to the core, the whole assembly accelerates, whites out,
   and the result is revealed in the core.

   The hardware is gold and follows the station tint (--st, so the Stations
   toggle still recolours it). The ENERGY is fixed aqua — it is the same
   magic whichever bench you are standing at, and letting it drift green in
   alchemy mode made the spin-up read as a loading spinner.

   Layering inside .lt-ring: forge art z1, .lt-core z2 (loot.css owns it),
   flash veil z3. Nothing here restyles .lt-core or the r1..r4 rings — they
   keep drawing the resting state, and the ceremony lives on top.
   ═══════════════════════════════════════════════════════════════════════ */

.lt-forge {
  position: absolute; inset: -6%; z-index: 1;
  pointer-events: none; opacity: 0;
  transition: opacity .5s ease;
  --fg-aqua: #0ac8b9;
  --fg-ice: #cdfafa;
}
/* Every phase except resting shows the art. */
.lt-forge.charge, .lt-forge.spin, .lt-forge.settle { opacity: 1; }

.lt-forge svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }

/* ── the energy arcs ──────────────────────────────────────────────── */
.fg-arcs circle {
  fill: none; stroke: var(--fg-aqua); transform-origin: 50% 50%;
  filter: drop-shadow(0 0 5px rgba(10, 200, 185, .65));
}
.fg-arcs .a-out { stroke-width: 3.2; }
.fg-arcs .a-mid { stroke-width: 1.6; opacity: .8; }

/* ── the swirling mist inside the ring ────────────────────────────────
   A masked conic sweep rather than particles: it has to sit UNDER a lit
   core and read as depth, and blurred geometry does that for one paint. */
.fg-vortex {
  position: absolute; inset: 12%; border-radius: 50%;
  background: conic-gradient(from 0deg,
    transparent 0deg, rgba(10, 200, 185, .62) 38deg, transparent 92deg,
    rgba(3, 151, 171, .50) 150deg, transparent 210deg,
    rgba(205, 250, 250, .40) 268deg, transparent 320deg);
  filter: blur(7px);
  opacity: 0; transition: opacity .55s ease;
  mask-image: radial-gradient(circle at 50% 50%, transparent 26%, #000 44%, #000 78%, transparent 92%);
  -webkit-mask-image: radial-gradient(circle at 50% 50%, transparent 26%, #000 44%, #000 78%, transparent 92%);
}
.lt-forge.charge .fg-vortex,
.lt-forge.spin .fg-vortex { opacity: 1; }
.lt-forge.settle .fg-vortex { opacity: .35; }

/* ── gold hardware: bezel, ticks, the three arms ──────────────────── */
.fg-hw path, .fg-hw circle, .fg-hw line {
  fill: none; stroke: var(--st); stroke-width: 1.6;
  stroke-linecap: round; stroke-linejoin: round;
  transform-origin: 50% 50%;
}
.fg-hw .hw-bezel { stroke-width: 2.2; }
.fg-hw .hw-tick { stroke-width: 1.4; opacity: .75; }
/* The arms carry the inputs into the core, so they brighten with the
   charge rather than sitting at full strength the whole time. */
.fg-hw .hw-arm { opacity: .55; transition: opacity .4s ease; }
.lt-forge.charge .fg-hw .hw-arm,
.lt-forge.spin .fg-hw .hw-arm { opacity: 1; }

/* ── the white-out ────────────────────────────────────────────────── */
.fg-flash {
  position: absolute; inset: -20%; z-index: 3; border-radius: 50%;
  background: radial-gradient(circle at 50% 50%,
    rgba(255, 255, 255, .92) 0%, rgba(205, 250, 250, .55) 34%, transparent 68%);
  opacity: 0; pointer-events: none;
}
.fg-flash.pop { animation: fg-flash 720ms cubic-bezier(.16, .8, .3, 1) both; }
@keyframes fg-flash {
  0%   { opacity: 0;   transform: scale(.72); }
  14%  { opacity: 1;   transform: scale(1); }
  100% { opacity: 0;   transform: scale(1.16); }
}

/* ── the core through the ceremony ────────────────────────────────────
   loot.css owns .lt-core's resting look; these only add on top of it. */
.lt-core.fg-lit {
  box-shadow: 0 0 70px rgba(10, 200, 185, .55), 0 0 26px var(--fg-ice, #cdfafa),
              inset 0 0 22px rgba(0, 0, 0, .55);
}
.lt-core.fg-pop { animation: fg-core-pop 820ms cubic-bezier(.18, 1.1, .32, 1) both; }
@keyframes fg-core-pop {
  0%   { transform: scale(.62); opacity: 0; }
  60%  { transform: scale(1.06); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}
/* the moment before the white-out: the core draws itself down to a point */
.lt-core.fg-suck { animation: fg-core-suck 460ms cubic-bezier(.5, 0, .9, .4) both; }
@keyframes fg-core-suck {
  0%   { transform: scale(1); }
  100% { transform: scale(.18); opacity: .2; }
}

/* ── the reveal caption, under the ring ───────────────────────────── */
.fg-said {
  position: absolute; left: 50%; bottom: -4px; transform: translateX(-50%);
  width: max(320px, 100%); text-align: center; z-index: 4; pointer-events: none;
  opacity: 0;
}
.fg-said.in { animation: fg-said-in 620ms cubic-bezier(.16, .8, .3, 1) both; }
@keyframes fg-said-in {
  from { opacity: 0; transform: translate(-50%, 12px); }
  to   { opacity: 1; transform: translate(-50%, 0); }
}
.fg-said b {
  display: block; font-family: var(--fd); font-size: 12px; letter-spacing: 2.6px;
  text-transform: uppercase; color: var(--fg-ice);
  text-shadow: 0 0 16px rgba(10, 200, 185, .6);
}
.fg-said small {
  display: block; font-size: 12px; color: var(--text-m); margin-top: 5px; line-height: 1.5;
}
.fg-said em { color: var(--st); font-style: normal; font-weight: 700; }

/* ═══════════════════════════════════════════════════════════════════════
   THE HAUL — what a craft actually paid out
   ---------------------------------------------------------------------
   The core reveal names the thing you made; it cannot lay out four
   potions and a crystal. This is the takeover screen for the yield, and
   it deliberately borrows the arena's post-match reward language — same
   gold rules, same framed emoji tiles, same "click to continue" — so a
   chest, a match and a craft all pay out in one visual vocabulary
   instead of three.
   ═══════════════════════════════════════════════════════════════════════ */

/* Visible is the RESTING state, and the fade is only on the way out. The
   obvious way round — start at 0, add a class to reveal — leaves the screen
   built, unhidden and permanently invisible whenever the transition never
   advances, which is exactly what happens in a background tab: the class
   lands, no frame composites, opacity stays 0, and a full-screen click
   swallower sits over the page. The entrance is carried by the header,
   footer and tile animations instead; if those freeze, nothing is lost but
   the flourish. */
.fg-got {
  position: fixed; inset: 0; z-index: 900;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  cursor: pointer; user-select: none; opacity: 1;
  transition: opacity .3s ease;
  --fg-aqua: #0ac8b9; --fg-ice: #cdfafa;
}
.fg-got.out { opacity: 0; }
.fg-got[hidden] { display: none; }

.gt-veil {
  position: absolute; inset: 0; z-index: 0;
  background: radial-gradient(ellipse at 50% 42%,
    rgba(8, 38, 48, .965) 0%, rgba(1, 10, 19, .988) 55%, rgba(1, 8, 15, .995) 100%);
  backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px);
}

.gt-head, .gt-foot { position: relative; z-index: 1; width: 100%; text-align: center; }
.gt-head {
  padding: 26px 0 18px;
  border-bottom: 1px solid rgba(200, 170, 110, .38);
  background: linear-gradient(180deg, rgba(1, 10, 19, .75), transparent);
  animation: gt-drop .6s cubic-bezier(.16, .8, .3, 1) both;
}
.gt-title {
  font-family: var(--fd); font-size: clamp(22px, 3.2vw, 40px);
  font-weight: 700; letter-spacing: .16em; text-transform: uppercase;
  color: var(--gold-l, #f0e6d2);
  text-shadow: 0 0 26px rgba(200, 170, 110, .45), 0 2px 14px rgba(0, 0, 0, .8);
}
.gt-sub {
  margin-top: 6px; font-size: 11.5px; letter-spacing: .22em;
  text-transform: uppercase; color: var(--text-m);
}
.gt-foot {
  padding: 16px 0 22px;
  border-top: 1px solid rgba(200, 170, 110, .38);
  background: linear-gradient(0deg, rgba(1, 10, 19, .75), transparent);
  font-size: 12px; letter-spacing: .2em; text-transform: uppercase; color: var(--text-d);
  animation: gt-rise .6s cubic-bezier(.16, .8, .3, 1) both;
}
@keyframes gt-drop { from { opacity: 0; transform: translateY(-14px); } to { opacity: 1; transform: none; } }
@keyframes gt-rise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }

.gt-body {
  position: relative; z-index: 1; flex: 1; width: 100%;
  display: flex; align-items: center; justify-content: center; padding: 18px 20px;
}
.gt-tiles {
  display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: center;
  gap: clamp(10px, 1.6vw, 22px);
}
.gt-tile {
  width: clamp(112px, 12vw, 170px);
  display: flex; flex-direction: column; align-items: center; opacity: 0;
}
.gt-tile.show { animation: gt-tile-in .6s cubic-bezier(.18, 1.1, .32, 1) both; }
@keyframes gt-tile-in {
  from { opacity: 0; transform: translateY(18px) scale(.88); filter: brightness(1.9); }
  to   { opacity: 1; transform: none; filter: none; }
}
.gt-frame {
  position: relative; width: 100%; aspect-ratio: 1;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(180deg, rgba(10, 40, 52, .92), rgba(1, 10, 19, .95));
  border: 1px solid var(--gold-dark, #785a28);
  box-shadow: inset 0 1px 0 rgba(240, 230, 210, .1), 0 14px 34px rgba(0, 0, 0, .6);
}
/* the clipped gold corners the arena tiles wear */
.gt-frame::before, .gt-frame::after {
  content: ''; position: absolute; width: 14px; height: 14px;
  border: 1px solid var(--gold, #c8aa6e); pointer-events: none;
}
.gt-frame::before { left: -1px; top: -1px; border-right: 0; border-bottom: 0; }
.gt-frame::after  { right: -1px; bottom: -1px; border-left: 0; border-top: 0; }
.gt-glyph {
  font-size: clamp(40px, 5.2vw, 74px); line-height: 1;
  filter: drop-shadow(0 0 16px rgba(10, 200, 185, .45));
}
.gt-count {
  width: 100%; text-align: center; padding: 5px 0 4px;
  font-family: var(--fd); font-size: clamp(14px, 1.4vw, 20px); font-weight: 700;
  color: var(--gold-l, #f0e6d2);
  background: linear-gradient(180deg, rgba(1, 10, 19, .95), rgba(1, 10, 19, .7));
  border: 1px solid var(--gold-dark, #785a28); border-top: 0;
  /* A one-off item (a splash crystal) carries no count, but the strip has to
     hold its height or that tile's name rides up out of line with the row. */
  min-height: 1.15em; line-height: 1.15;
}
.gt-name {
  margin-top: 7px; font-size: 10.5px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--text-m); text-align: center;
}

@media (prefers-reduced-motion: reduce) {
  .gt-head, .gt-foot, .gt-tile.show { animation: none; }
  .gt-tile { opacity: 1; }
}

/* ═══════════════════════════════════════════════════════════════════════
   THE DIAL — level up / infuse / burn, on the rim
   ---------------------------------------------------------------------
   Three actions sat in a flat list under the card and read as a form. They
   are now three buttons on the ring, at the ends of the arms the forge
   already draws (12, 4 and 8 o'clock). The chosen one rotates up to the
   lead position and grows; the other two shrink and stay live. Choosing
   Level Up opens its two cost slots — fragments and gold — between the
   button and the card, so the price is on the ring rather than in prose.

   Positions are three fixed points; options MOVE between them, which is
   what makes picking one feel like turning a dial instead of toggling a
   radio button.
   ═══════════════════════════════════════════════════════════════════════ */

.lt-dial { position: absolute; inset: 0; z-index: 4; pointer-events: none; }
.lt-dial.on { pointer-events: auto; }

/* Shared skeleton. .dl-face is the pressable body — a disc on the ring, a
   square on the bench — and .dl-txt is the label under it, always outside
   the body so a long verb never has to fit inside a circle. */
.dl-opt, .dl-slot {
  display: flex; flex-direction: column; align-items: center; gap: 5px;
  font-family: inherit; text-align: center; background: none; border: 0; padding: 0;
}
.dl-opt { color: var(--text-m); cursor: pointer; }
.dl-opt:disabled { opacity: .36; cursor: not-allowed; }
.dl-slot { pointer-events: none; }

.dl-face {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  background: linear-gradient(180deg, rgba(9, 20, 34, .96), rgba(2, 10, 18, .98));
  border: 1px solid rgba(200, 170, 110, .34);
  box-shadow: 0 6px 20px rgba(0, 0, 0, .55), inset 0 1px 0 rgba(240, 230, 210, .06);
  transition: border-color .2s ease, box-shadow .25s ease, transform .2s ease,
              width .3s ease, height .3s ease;
}
.dl-ic { font-size: 17px; line-height: 1; }
.dl-v { display: block; font-size: 9.5px; letter-spacing: 1.4px; text-transform: uppercase; font-weight: 700; }
.dl-q { display: none; font-size: 10px; color: var(--text-d); }
.dl-slot .s-ic { font-size: 15px; line-height: 1.05; }
.dl-slot b { font-size: 12px; font-weight: 700; color: var(--text-l); }
.dl-slot small { font-size: 8.5px; letter-spacing: 1.2px; text-transform: uppercase; color: var(--text-d); }
.dl-slot.ok  .dl-face { border-color: rgba(10, 200, 185, .55); }
.dl-slot.ok  b { color: #6fe4d8; }
.dl-slot.bad .dl-face { border-color: rgba(198, 74, 74, .55); }
.dl-slot.bad b { color: #e08585; }

.dl-opt:hover:not(:disabled) { color: var(--text-l); }
.dl-opt:hover:not(:disabled) .dl-face { border-color: var(--st); }

/* the picked one: bigger, and it says what it will cost */
.dl-opt.lead { color: var(--text-l); }
.dl-opt.lead .dl-ic { font-size: 23px; }
.dl-opt.lead .dl-v { font-size: 11px; letter-spacing: 2px; }
.dl-opt.lead .dl-q { display: block; margin-top: 1px; }
/* armed = pressing it commits. Aqua, because gold is the resting frame
   colour everywhere else on this page and would not read as "go". */
.dl-opt.lead:not(:disabled) .dl-face {
  border-color: var(--fg-aqua, #0ac8b9);
  box-shadow: 0 0 0 1px rgba(10, 200, 185, .16), 0 10px 30px rgba(0, 0, 0, .6),
              0 0 26px rgba(10, 200, 185, .28);
}
.dl-opt.lead:not(:disabled):hover .dl-face {
  box-shadow: 0 0 0 1px rgba(10, 200, 185, .4), 0 10px 30px rgba(0, 0, 0, .6),
              0 0 38px rgba(10, 200, 185, .5);
}
.dl-opt.lead:not(:disabled):active .dl-face { transform: scale(.94); }

/* armed: an irreversible action asking once. Red, and it pulses so it is
   obvious the button is in a different state than the one just pressed. */
.dl-opt.lead.armed { color: #ffd9d9; }
.dl-opt.lead.armed .dl-face {
  border-color: #c64a4a;
  animation: dl-armed 1.1s ease-in-out infinite;
}
@keyframes dl-armed {
  0%, 100% { box-shadow: 0 0 0 1px rgba(198, 74, 74, .3), 0 10px 30px rgba(0, 0, 0, .6), 0 0 20px rgba(198, 74, 74, .3); }
  50%      { box-shadow: 0 0 0 1px rgba(198, 74, 74, .6), 0 10px 30px rgba(0, 0, 0, .6), 0 0 36px rgba(198, 74, 74, .6); }
}

/* ═══ LAYOUT A — on the ring ═══════════════════════════════════════════
   Everything seated on the circle IS a circle. A square button sitting on
   a rim reads as a mistake, so the faces go round and the labels drop
   outside them where a long verb has room. */
.lt-dial[data-layout="ring"] .dl-opt,
.lt-dial[data-layout="ring"] .dl-slot {
  position: absolute; left: var(--x); top: var(--y);
  transform: translate(-50%, -50%);
  width: 96px;
  transition: left .42s cubic-bezier(.3, .9, .3, 1), top .42s cubic-bezier(.3, .9, .3, 1),
              opacity .2s ease;
}
.lt-dial[data-layout="ring"] .dl-face { border-radius: 50%; width: 54px; height: 54px; }
.lt-dial[data-layout="ring"] .dl-opt.lead .dl-face { width: 76px; height: 76px; }
.lt-dial[data-layout="ring"] .dl-slot .dl-face { width: 50px; height: 50px; gap: 1px; }
.lt-dial[data-layout="ring"] .dl-txt {
  /* pulled out of flow so a two-line label can't shove the disc off centre */
  position: absolute; top: 100%; left: 50%; transform: translateX(-50%);
  width: 100%; margin-top: 5px;
  text-shadow: 0 2px 8px rgba(1, 8, 15, .95);
}
.lt-dial[data-layout="ring"] .dl-slot { animation: dl-pop 380ms cubic-bezier(.18, 1.1, .32, 1) both; }
.lt-dial[data-layout="ring"] .dl-slot:last-child { animation-delay: 70ms; }
@keyframes dl-pop {
  from { opacity: 0; transform: translate(-50%, -50%) scale(.7); }
  to   { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}

/* ═══ LAYOUT B — the bench ═════════════════════════════════════════════
   Options and materials as square buttons in one bracketed tray under the
   ring, the shape the client's own loot bench uses. Positions are ignored
   here; the row lays itself out. */
.lt-dial[data-layout="bench"] {
  position: absolute; inset: auto; top: calc(100% + 18px); left: 50%;
  transform: translateX(-50%); width: max-content; max-width: 92vw;
}
.dl-bar {
  display: flex; align-items: flex-start; gap: 14px;
  padding: 12px 22px 10px;
  border: 1px solid rgba(200, 170, 110, .3);
  border-top-width: 0;
  background: linear-gradient(180deg, rgba(6, 16, 28, .82), rgba(2, 10, 18, .5));
  /* the notched bracket the client hangs its tray from */
  clip-path: polygon(0 0, 46% 0, 50% 11px, 54% 0, 100% 0,
                     100% 100%, 0 100%);
  position: relative;
}
.dl-bar::before {
  content: ''; position: absolute; left: 12px; right: 12px; top: 0; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(200, 170, 110, .5) 18%,
              transparent 46%, transparent 54%, rgba(200, 170, 110, .5) 82%, transparent);
}
.dl-group { display: flex; align-items: flex-start; gap: 12px; }
.dl-sep { width: 1px; align-self: stretch; background: rgba(200, 170, 110, .22); }
.lt-dial[data-layout="bench"] .dl-opt,
.lt-dial[data-layout="bench"] .dl-slot { position: static; transform: none; width: 74px; }
.lt-dial[data-layout="bench"] .dl-face {
  border-radius: 3px; width: 54px; height: 54px;
}
.lt-dial[data-layout="bench"] .dl-opt.lead .dl-face { width: 62px; height: 62px; }
.lt-dial[data-layout="bench"] .dl-slot .dl-face { width: 48px; height: 48px; gap: 1px; }
.lt-dial[data-layout="bench"] .dl-slot { animation: dl-rise 340ms cubic-bezier(.18, 1.1, .32, 1) both; }
.lt-dial[data-layout="bench"] .dl-slot:last-child { animation-delay: 70ms; }
@keyframes dl-rise {
  from { opacity: 0; transform: translateY(10px) scale(.86); }
  to   { opacity: 1; transform: none; }
}

/* the dial gets out of the way while the forge is performing */
.lt-ring.busy .lt-dial { opacity: 0; pointer-events: none; transition: opacity .3s ease; }

@media (max-width: 1100px) {
  .lt-dial[data-layout="ring"] .dl-face { width: 44px; height: 44px; }
  .lt-dial[data-layout="ring"] .dl-opt.lead .dl-face { width: 62px; height: 62px; }
  .lt-dial[data-layout="ring"] .dl-slot .dl-face { width: 42px; height: 42px; }
  .dl-bar { gap: 10px; padding: 10px 14px 8px; }
  .dl-group { gap: 8px; }
  .lt-dial[data-layout="bench"] .dl-opt,
  .lt-dial[data-layout="bench"] .dl-slot { width: 60px; }
}

/* ── calm motion ──────────────────────────────────────────────────────
   The spin is driven by WAAPI, which forge.js skips outright under this
   query; what is left here are the CSS-only beats. */
@media (prefers-reduced-motion: reduce) {
  .fg-flash.pop, .lt-core.fg-pop, .lt-core.fg-suck, .fg-said.in { animation-duration: 1ms; }
  .fg-vortex { filter: none; }
  .lt-dial .dl-opt { transition: none; }
  .lt-dial .dl-slot { animation: none; }
  .dl-opt.lead.armed .dl-face { animation: none; }
}
