/* The Prize House — button system.
 *
 * The brief caps button state at 120ms ease-out and bans pulsing and blinking,
 * so the richness here is in WHAT changes, not how long it takes or how often.
 * Nothing animates at rest. Every effect is a response to the user.
 *
 * One exception, flagged: the sheen on the primary button runs 420ms, because a
 * sweep cannot read in 120. It fires once per hover and never idles.
 */

.btn{
  --lift: 0px;
  position:relative; isolation:isolate; overflow:hidden;
  display:inline-flex; align-items:center; justify-content:center; gap:10px;
  padding:16px 28px; min-height:52px;            /* 44px hit target floor, cleared */
  border:0; border-radius:var(--radius-md); cursor:pointer;
  font-family:var(--font-display); font-weight:700; font-size:16px;
  letter-spacing:.06em; text-transform:uppercase; text-decoration:none;
  white-space:nowrap; -webkit-tap-highlight-color:transparent;
  transform:translateY(var(--lift));
  transition:transform 120ms ease-out, background-color 120ms ease-out,
             border-color 120ms ease-out, color 120ms ease-out,
             box-shadow 120ms ease-out;
}
.btn:hover{ --lift:-1px }
.btn:active{ --lift:1px; transition-duration:60ms }   /* press reads faster than release */

/* Focus is drawn, not coloured: the ring scales out from the edge so it is
   visible on any surface and does not rely on the brand hue. */
.btn:focus-visible{ outline:none }
.btn:focus-visible::after{
  content:""; position:absolute; inset:-4px; border-radius:calc(var(--radius-md) + 4px);
  border:2px solid var(--text); animation:btn-ring 160ms ease-out both;
}
@keyframes btn-ring{ from{ inset:0; opacity:0 } to{ inset:-4px; opacity:1 } }

/* ---------------------------------------------------------------
   PRIMARY. The gradient button. One per view, by brand rule.
   Ink text: white fails across the whole sweep (2.46 / 3.34 / 4.36).
   The sweep is 200% wide and slides, so hover moves the gradient
   through the button rather than swapping a colour.
   --------------------------------------------------------------- */
.btn--primary{
  color:var(--brand-ink);
  background:var(--sweep); background-size:200% 100%; background-position:0% 0;
  transition:transform 120ms ease-out, background-position 120ms ease-out,
             box-shadow 120ms ease-out;
}
.btn--primary:hover{ background-position:100% 0; box-shadow:0 8px 22px -12px rgba(252,79,45,.85) }
.btn--primary:active{ background-position:60% 0 }

/* the sheen: one pass, hover only, never at rest */
.btn--primary::before{
  content:""; position:absolute; inset:0; z-index:-1; pointer-events:none;
  background:linear-gradient(105deg,transparent 35%,rgba(255,255,255,.38) 50%,transparent 65%);
  transform:translateX(-120%);
}
.btn--primary:hover::before{ animation:btn-sheen 420ms ease-out both }
@keyframes btn-sheen{ to{ transform:translateX(120%) } }

/* ---------------------------------------------------------------
   SOLID. Flame fill, for every other real action on the view.
   --------------------------------------------------------------- */
.btn--solid{ background:var(--flame); color:var(--brand-ink) }
.btn--solid:hover{ background:var(--brand-hover); box-shadow:0 8px 20px -14px rgba(252,134,9,.9) }

/* ---------------------------------------------------------------
   GHOST. Line, not fill, which is the brand's material rule.
   Flame wipes in from the left edge and the label flips to ink.
   --------------------------------------------------------------- */
.btn--ghost{ background:transparent; color:var(--text); box-shadow:inset 0 0 0 1px var(--line) }
.btn--ghost::before{
  content:""; position:absolute; inset:0; z-index:-1; background:var(--flame);
  transform:scaleX(0); transform-origin:left center;
  transition:transform 120ms ease-out;
}
.btn--ghost:hover{ color:var(--brand-ink); box-shadow:inset 0 0 0 1px var(--flame) }
.btn--ghost:hover::before{ transform:scaleX(1) }

/* ---------------------------------------------------------------
   QUIET. Text action. The rule draws from the left, it does not fade.
   --------------------------------------------------------------- */
.btn--quiet{
  padding:6px 0; min-height:0; background:none; color:var(--text-2);
  letter-spacing:.04em; font-size:14px; border-radius:0; overflow:visible;
}
.btn--quiet::before{
  content:""; position:absolute; left:0; right:0; bottom:0; height:1px; background:var(--flame);
  transform:scaleX(0); transform-origin:left center; transition:transform 120ms ease-out;
}
.btn--quiet:hover{ color:var(--text) }
.btn--quiet:hover::before{ transform:scaleX(1) }

/* ---------------------------------------------------------------
   SOLD OUT and DRAWN. Never filled: brand rule 4, and it is what
   keeps the greyscale separation (surface 15 against flame 155).
   No hover, because there is nothing to do.
   --------------------------------------------------------------- */
.btn--sold{
  background:var(--surface-1); color:var(--text-2);
  box-shadow:inset 0 0 0 1px var(--line); cursor:default;
}
.btn--sold:hover{ --lift:0px }

/* ---------------------------------------------------------------
   The arrow travels. Used on "View all" style actions.
   --------------------------------------------------------------- */
.btn__arrow{ display:block; transition:transform 120ms ease-out }
.btn:hover .btn__arrow{ transform:translateX(4px) }

/* ---------------------------------------------------------------
   Working state. A flame bar crosses the button once per second while
   it waits. This is feedback, not decoration, so it is allowed to loop.
   --------------------------------------------------------------- */
.btn[data-busy]{ pointer-events:none; color:transparent }
.btn[data-busy]::after{
  content:""; position:absolute; left:0; bottom:0; height:2px; width:40%;
  background:var(--flame); animation:btn-busy 900ms ease-in-out infinite;
}
@keyframes btn-busy{ 0%{ transform:translateX(-100%) } 100%{ transform:translateX(350%) } }

/* Chips share the 120ms state budget. */
.chip{
  display:inline-flex; align-items:center; gap:6px; padding:5px 10px;
  border-radius:var(--radius-sm); font-family:var(--font-display);
  font-weight:700; font-size:11px; letter-spacing:.12em; text-transform:uppercase;
  transition:background-color 120ms ease-out, color 120ms ease-out;
}
.chip--live{ background:var(--rose); color:var(--brand-ink) }          /* not animated, by rule */
.chip--closing{ background:var(--rose); color:var(--brand-ink) }
.chip--instant{ background:transparent; color:var(--flame); box-shadow:inset 0 0 0 1px var(--flame) }
.chip--sold{ background:transparent; color:var(--text-2); box-shadow:inset 0 0 0 1px var(--line) }

/* Reduced motion: every transition above 120ms goes, the sheen and the busy
   bar stop entirely, and state still changes so nothing becomes unreadable. */
@media (prefers-reduced-motion:reduce){
  .btn, .btn *, .chip{ transition-duration:0ms!important }
  .btn--primary:hover::before, .btn[data-busy]::after{ animation:none }
  .btn:focus-visible::after{ animation:none; inset:-4px; opacity:1 }
  .btn--ghost::before, .btn--quiet::before{ transition:none }
}
