/* ==========================================================================
   HARRY POTTER ONLINE — LOGIN FX  (wave 2, agent G3)
   The enchantment layer. Loads LAST (after wizloria.css and login-luxe.css),
   so every rule here wins on order.

   RULES THIS FILE OBEYS
   ---------------------
   · It adds NOTHING to layout. Every surface it paints is position:fixed or
     position:absolute + pointer-events:none, so `scrollHeight` and
     `scrollWidth` are untouched. No margins, no paddings, no sizes, no
     display changes. THE ONE LAW survives.
   · It never blocks a click. Every overlay is pointer-events:none; the only
     pseudo-elements that live inside interactive elements (.btn, .lux-char)
     belong to those elements, so the hit test still lands on the control.
   · It animates transform / opacity / filter only. The four full-screen mote
     and light fields are static paints that are merely translated — the
     texture is rasterised once and composited from then on. The exceptions
     are all tiny: two background-position sheens (login plate, sign-up card),
     the 1px rune bar's travelling glint, and the CTA's box-shadow breath.
   · It never darkens. The note for round 3 was "it is TOO DARK": every
     atmospheric layer here is additive light — moonlight, candle bloom, torch
     pools, a cool rim of LIGHT instead of a vignette. The ONLY dark ink in
     this file is the per-card CONTACT SHADOW (§8), which is a 38px ellipse
     under each portrait; without it the rail floats off the ground. It is
     night blue, never black, and it is never a sheet.
   · prefers-reduced-motion freezes the whole thing.
   · ⛔ TWO CROSS-FILE COUPLINGS ARE LOAD-BEARING, both documented in place:
     §4 reads login-luxe's `--pl-y/--pl-x` (board geometry) and its
     `--wl-candle/--wl-torch` light tokens; §8 restates login-cards.js's
     `lcAttract` so its class toggle cannot restart this file's card entrance.

   PAINT ORDER (why the effects land where they do)
   ------------------------------------------------
   Root stacking context, back to front:
       #wizScene3d          z1   the live castle
       body::before         z2   MOONLIGHT RAKE     (before .scene-grade in
                                 tree order, so it sits UNDER the grade — it
                                 is light in the far air)
       .scene-grade         z2   grade + vignette
         ::before           —    the arrival sweep
       body::after          z2   NEAR BOKEH         (after .lux-stage in tree
                                 order but z2 < z3, so: over the grade, under
                                 every piece of UI)
       .topbar / .lux-stage z3
   .lux-stage is `position:relative;z-index:3` → a stacking context, so a
   pseudo inside it with `z-index:-1` paints BEHIND the stage's own content
   but still above everything at z2. Tree order between those layers:
       .lux-stage::before   atmosphere (moon pool, candle band, torch pools)
       .lux-air::before     dust motes, drifting up-left      (far,  46s)
       .lux-air::after      embers, rising                    (mid,  34s)
       .lux-stage::after    aurora wisps
   The plate's own candle (§4) is one level deeper still — `z-index:-2` inside
   .lux-signin, i.e. BEHIND login-luxe's board, so it reads as light spilling
   out from under the plate instead of a wash painted over the oak.
   ...then .lux-select (z:0), .lux-hero / .lux-signin (z:2) on top.

   PARALLAX LADDER (four fields, four speeds — this is what stops the page
   reading as a still frame):
       rake      body::before   26s sway        farthest, biggest, dimmest
       dust      .lux-air::b    46s up-left     far
       embers    .lux-air::a    34s rising      mid
       bokeh     body::after    19s up-left     near, big, out of focus

   HOSTS CLAIMED BY THIS FILE (all free in login-luxe.css / wizloria.css):
     body::before  body::after       .scene-grade::before
     .lux-stage::before/::after      .lux-air::before/::after
     .lux-banner::before/::after     .lux-banner img
     .lux-signin-bar::before/::after .lux-signin-form::before
     .field::before/::after          .btn::before (+ .btn::after re-cut)
     .lux-signin-go .btn-face::after
     .lux-char::before/::after       .lux-char-art::before
     .lux-loginbtn::after            .lux-signin-seal::after
     .lux-auth-veil::after           .lux-auth-card .form::before
     .lux-auth-card .wl-seal::after
   ⚠ `.lux-signin-form::before` is a NEW claim this wave (the candle). If the
     owner of login-luxe.css wants that host back, the candle can move to
     `.lux-signin-meta::before` with a bottom-anchored inset.
   ========================================================================== */

/* ══════════════════ 1. ATMOSPHERE — light, never a black wash ════════════
   A frame made of glow instead of vignette. The moon really is up over the
   castle's RIGHT shoulder (login3d.js: MOON_AT, measured on the shipped page
   at ~72% x / 29% y), so the moon pool is painted there and not at the top
   centre where round 3 had it. Two torch pools at the floor line, a candle
   band where the login plate sits, and a faint cool halo that closes the
   corners by LIFTING the middle rather than sinking the edges.              */

.lux-stage::before{
  content:'';
  position:fixed;inset:0;z-index:-1;
  pointer-events:none;
  background:
    /* the moon's own pool of light — cool, tight, over the right shoulder */
    radial-gradient(26% 22% at 72% 27%, rgba(214,228,255,.115), transparent 70%),
    /* its wide bleed into the sky */
    radial-gradient(64% 46% at 70% 20%, rgba(159,192,255,.055), transparent 76%),
    /* candlelight where the login plate stands — warm, wide, low alpha.
       The colours below are login-luxe's own light tokens (--wl-candle
       #ffc478, --wl-torch #ffa24a), so the CSS air matches the 3D lights. */
    radial-gradient(44% 17% at 50% 57%, rgba(var(--wl-candle,255,196,120),.085), transparent 74%),
    /* two torch pools washing the character rail from the wings */
    radial-gradient(32% 24% at 5%  103%, rgba(var(--wl-torch,255,162,74),.10), transparent 72%),
    radial-gradient(32% 24% at 95% 103%, rgba(var(--wl-torch,255,162,74),.10), transparent 72%),
    /* the courtyard floor the rail stands on — warm, wide, very low */
    radial-gradient(66% 16% at 50% 103%, rgba(var(--wl-candle,255,196,120),.115), transparent 76%),
    /* the "vignette": a cool rim of LIGHT, so the frame reads without dark */
    radial-gradient(128% 98% at 50% 46%, transparent 62%, rgba(126,166,236,.045) 100%);
  animation:fxWash 1.9s ease .15s both, fxBreathe 13s ease-in-out 2s infinite;
}

/* aurora — two lazy wisps of cold light that cross the sky. 6% opacity: it
   reads as air, never as a filter over the castle. */
.lux-stage::after{
  content:'';
  position:fixed;inset:-14% -22%;z-index:-1;
  pointer-events:none;
  opacity:.6;
  background:
    radial-gradient(30% 16% at 26% 22%, rgba(120,190,255,.070), transparent 70%),
    radial-gradient(24% 13% at 74% 15%, rgba(178,150,255,.055), transparent 72%),
    radial-gradient(38% 10% at 52% 34%, rgba(140,220,215,.035), transparent 74%);
  animation:fxAurora 46s ease-in-out infinite, fxWash 2.6s ease .5s both;
}

/* ── MOONLIGHT RAKE — shafts falling out of the moon ──────────────────────
   A repeating band of pale light rotated to the moon's shoulder, then MASKED
   by an ellipse so the shafts exist in the upper sky and dissolve before they
   reach the rail. The mask is static: only opacity and a ~2% translate
   animate, so the layer rasterises once and is composited from then on.

   Geometry note — the mask's percentages resolve against THIS box, not the
   viewport. inset:-10% makes the box 120% x 120% starting at -10%/-10%, so a
   viewport point (x,y) is at ((x+10)/120, (y+10)/120) here: the moon at
   72%/27% of the screen is 68%/31% of this box.
   ⚠ …and the mask is deliberately NOT centred there. login3d paints a wide
   moon halo, so the sky is at its brightest exactly at the moon and shafts
   drawn on top of it are invisible (measured — first cut had the mask on the
   moon and read as nothing). The pool is pushed DOWN-LEFT, into the darker
   sky the shafts fall through, which is also where a real shaft is visible. */
body.luxe::before{
  content:'';
  position:fixed;inset:-10%;z-index:2;
  pointer-events:none;
  background:repeating-linear-gradient(101deg,
    transparent 0 76px,
    rgba(206,224,255,.055) 96px,
    rgba(244,249,255,.125) 113px,
    rgba(206,224,255,.055) 130px,
    transparent 150px 272px);
  -webkit-mask-image:radial-gradient(54% 62% at 60% 37%,
    rgba(0,0,0,1) 0%, rgba(0,0,0,.80) 30%, rgba(0,0,0,.36) 58%, transparent 84%);
          mask-image:radial-gradient(54% 62% at 60% 37%,
    rgba(0,0,0,1) 0%, rgba(0,0,0,.80) 30%, rgba(0,0,0,.36) 58%, transparent 84%);
  animation:fxRake 26s ease-in-out infinite, fxWash 3.4s ease 1.1s both;
}
@keyframes fxRake{
  0%,100%{opacity:.5;transform:translate3d(0,0,0)}
  50%    {opacity:1;transform:translate3d(-1.8%,1.2%,0)}
}

/* ── the one-shot: a band of light crosses the castle as the page arrives ──
   Hosted on .scene-grade (position:fixed, z:2, pointer-events:none, and its
   ::before is free) so the sweep travels over the 3D castle and UNDER every
   piece of UI. .scene-grade carries no transform of its own, so an absolutely
   positioned child here can never be re-parented by a filling animation.   */
.scene-grade::before{
  content:'';
  position:absolute;inset:-12% -46%;
  pointer-events:none;
  background:linear-gradient(104deg,
    transparent 38%,
    rgba(186,214,255,.11) 45%,
    rgba(255,251,236,.28) 50%,
    rgba(236,200,132,.14) 55%,
    transparent 62%);
  transform:translate3d(-58%,0,0);
  animation:fxSpellSweep 2.1s cubic-bezier(.34,.02,.2,1) .2s both;
}
@keyframes fxSpellSweep{
  0%  {opacity:0;transform:translate3d(-58%,0,0)}
  16% {opacity:1}
  78% {opacity:1}
  100%{opacity:0;transform:translate3d(58%,0,0)}
}

/* ══════════════════ 2. MOTES — three drifting fields ═════════════════════
   Each field is ONE static paint (a tile of soft radial dots) that is only
   ever translated by exactly one tile, so the loop is seamless and the layer
   never repaints. `inset` is one tile larger than the viewport so the
   trailing edge is never empty. Three tile sizes + three periods = three
   apparent depths; that parallax is the whole point.                        */

.lux-air{position:relative}

/* — FAR: fine cold dust, up and to the left, very slow —
     NOTE the explicit `circle <r>` radius on every gradient: a bare
     `radial-gradient(circle, …)` sizes itself to farthest-corner, i.e. one
     "dot" the size of the whole tile. That reads as fog, not dust. */
.lux-air::before{
  content:'';
  position:fixed;inset:-190px;z-index:-1;
  pointer-events:none;
  opacity:.85;
  background-repeat:repeat;
  background-size:180px 180px;
  background-image:
    radial-gradient(circle 2.4px at 50% 50%, rgba(255,255,255,.95), rgba(198,222,255,.45) 42%, transparent 100%),
    radial-gradient(circle 1.6px at 50% 50%, rgba(255,248,226,.90), rgba(240,214,150,.40) 44%, transparent 100%),
    radial-gradient(circle 1.9px at 50% 50%, rgba(226,238,255,.80), rgba(170,205,255,.34) 44%, transparent 100%),
    radial-gradient(circle 1.3px at 50% 50%, rgba(255,255,255,.70), rgba(200,220,255,.28) 46%, transparent 100%),
    radial-gradient(circle 2.1px at 50% 50%, rgba(232,242,255,.85), rgba(178,210,255,.36) 42%, transparent 100%),
    radial-gradient(circle 1.5px at 50% 50%, rgba(255,240,204,.72), rgba(230,196,132,.26) 46%, transparent 100%),
    radial-gradient(circle 1.1px at 50% 50%, rgba(255,255,255,.62), rgba(210,228,255,.22) 48%, transparent 100%),
    /* two soft halos give the field depth without becoming fog */
    radial-gradient(circle 9px  at 50% 50%, rgba(214,232,255,.10), transparent 100%),
    radial-gradient(circle 11px at 50% 50%, rgba(255,232,186,.09), transparent 100%);
  background-position:
     14px  22px,  96px  61px,  47px 132px, 143px 104px,
    120px  16px,  28px  96px, 165px 152px,
     96px  61px, 120px  16px;
  animation:fxDustDrift 46s linear infinite, fxWash 3s ease .6s both;
}

/* — MID: warm embers rising off the courtyard, fewer and bigger — */
.lux-air::after{
  content:'';
  position:fixed;inset:-280px;z-index:-1;
  pointer-events:none;
  opacity:.8;
  background-repeat:repeat;
  background-size:270px 270px;
  background-image:
    radial-gradient(circle 2.6px at 50% 50%, rgba(255,238,196,1),   rgba(255,186,92,.55) 34%, transparent 100%),
    radial-gradient(circle 2.0px at 50% 50%, rgba(255,244,214,.95), rgba(255,196,110,.45) 36%, transparent 100%),
    radial-gradient(circle 3.0px at 50% 50%, rgba(255,232,178,.85), rgba(255,176,84,.36) 34%, transparent 100%),
    radial-gradient(circle 1.7px at 50% 50%, rgba(255,248,226,.85), rgba(255,206,126,.32) 38%, transparent 100%),
    radial-gradient(circle 2.2px at 50% 50%, rgba(255,228,172,.75), rgba(255,170,80,.28) 36%, transparent 100%),
    /* the ember halos — the only large soft shapes in the field */
    radial-gradient(circle 15px at 50% 50%, rgba(255,178,84,.13), rgba(255,150,60,.05) 44%, transparent 100%),
    radial-gradient(circle 13px at 50% 50%, rgba(255,196,110,.11), transparent 100%),
    radial-gradient(circle 18px at 50% 50%, rgba(255,164,72,.08), transparent 100%);
  background-position:
     36px 210px, 188px  58px,  92px 124px, 240px 176px, 132px 246px,
     36px 210px,  92px 124px, 240px 176px;
  /* ORDER MATTERS: when two animations touch the same property the LAST one
     wins. fxWash fills forward (its implicit `to` is the underlying opacity),
     so the perpetual glow has to wait for the wash to finish rather than sit
     in front of it in the list. */
  animation:fxEmberRise 34s linear infinite,
            fxEmberGlow 11s ease-in-out 4.4s infinite,
            fxWash 3.4s ease .8s backwards;
}

/* — NEAR: big, soft, out-of-focus specks passing close to the lens.
     The "blur" is baked into the gradient stops (the dot fades over its whole
     radius) rather than bought with filter:blur() — a filter here would cost
     a full-screen blur pass every frame over a live WebGL canvas.
     Hosted on body::after so it can sit ABOVE .scene-grade (same z:2, later
     in tree order) while staying below every piece of UI (z:3).            */
body.luxe::after{
  content:'';
  position:fixed;inset:-340px;z-index:2;
  pointer-events:none;
  opacity:.5;
  background-repeat:repeat;
  background-size:330px 330px;
  background-image:
    radial-gradient(circle 7px  at 50% 50%, rgba(226,240,255,.30), rgba(190,218,255,.10) 46%, transparent 100%),
    radial-gradient(circle 5px  at 50% 50%, rgba(255,240,208,.28), rgba(255,206,132,.09) 48%, transparent 100%),
    radial-gradient(circle 9px  at 50% 50%, rgba(214,232,255,.20), rgba(160,198,255,.06) 44%, transparent 100%),
    radial-gradient(circle 4px  at 50% 50%, rgba(255,250,235,.26), rgba(226,208,168,.08) 50%, transparent 100%),
    radial-gradient(circle 11px at 50% 50%, rgba(255,214,158,.14), transparent 100%);
  background-position:
     58px 244px, 262px  92px, 148px 300px, 300px 200px, 96px 40px;
  animation:fxNearDrift 19s linear infinite, fxWash 4s ease 1.3s both;
}

@keyframes fxWash{from{opacity:0}}
@keyframes fxBreathe{0%,100%{opacity:1}50%{opacity:.84}}
@keyframes fxAurora{
  0%,100%{transform:translate3d(-2.5%,0,0) scale(1)}
  50%    {transform:translate3d( 2.5%,-1.6%,0) scale(1.07)}
}
@keyframes fxDustDrift{
  from{transform:translate3d(0,0,0)}
  to  {transform:translate3d(-180px,-180px,0)}
}
@keyframes fxNearDrift{
  from{transform:translate3d(0,0,0)}
  to  {transform:translate3d(-330px,-330px,0)}
}
/* the horizontal sway returns to 0 at 100% so the tile still lines up */
@keyframes fxEmberRise{
  0%  {transform:translate3d(0,0,0)}
  35% {transform:translate3d(11px,-94px,0)}
  70% {transform:translate3d(-9px,-189px,0)}
  100%{transform:translate3d(0,-270px,0)}
}
@keyframes fxEmberGlow{0%,100%{opacity:.8}45%{opacity:1}}

/* ══════════════════ 3. HOUSE BANNERS — wind ══════════════════════════════
   login-luxe hangs them with `luxSway 9s` (a flat ±1.1° rocker) and they read
   as painted-on. Real cloth does three things at once, so this gives them
   three: the whole banner swings from its pole (parent), the cloth itself
   ripples and breathes (the img, a SECOND transform that composes with the
   swing), and a highlight travels down the weave as it turns (::after).

   ⚠ Restating the shorthand also restates login-luxe's `luxFade` entrance —
   it has to, because `animation` is one property. If login-luxe's banner
   entrance ever changes, this list is the copy that needs updating.        */
.lux-banner{
  opacity:.56;
  animation:fxBannerWind 11s ease-in-out infinite, luxFade 1.6s ease .8s both;
}
.lux-banner-r{animation-delay:-5.5s,.8s}
@keyframes fxBannerWind{
  0%   {transform:rotate(-1.35deg)}
  22%  {transform:rotate( .5deg)}
  38%  {transform:rotate(1.5deg)}
  61%  {transform:rotate( .15deg)}
  79%  {transform:rotate(-.95deg)}
  100% {transform:rotate(-1.35deg)}
}

/* the cloth's own ripple — a separate transform on the child, so the two
   compose into something that is not a metronome. WIZART injects
   `img.wlart-img`, so the animation starts the moment the art lands: the
   banner UNFURLS on arrival and then never stops breathing. */
.lux-banner img{
  transform-origin:50% 0;
  animation:fxUnfurl .95s cubic-bezier(.24,1.02,.42,1) backwards,
            fxCloth 6.4s ease-in-out .95s infinite;
}
.lux-banner-r img{animation-delay:.12s,-2.1s}
@keyframes fxUnfurl{
  from{opacity:0;transform:scaleY(.16) skewX(5deg)}
  60% {opacity:1}
  to  {opacity:1;transform:scaleY(1) skewX(0)}
}
@keyframes fxCloth{
  0%,100%{transform:skewX(-1.5deg) scaleY(1)}
  30%    {transform:skewX(1.1deg)  scaleY(.988)}
  64%    {transform:skewX(-.4deg)  scaleY(1.012)}
}

/* a torch behind each banner: the cloth is LIT, not just tinted.
   .lux-banner carries `filter:drop-shadow()`, which makes it a stacking
   context, so z-index:-1 stays trapped inside it and paints behind the art.
   The parent's mask fades the pool out along with the cloth's tail. */
.lux-banner::before{
  content:'';
  position:absolute;z-index:-1;pointer-events:none;
  inset:-42% -86% -16%;
  background:radial-gradient(50% 46% at 50% 30%,
    rgba(var(--wl-candle,255,196,120),.46), rgba(var(--wl-torch,255,162,74),.18) 44%, transparent 74%);
  animation:fxTorch 4.9s ease-in-out infinite;
}
.lux-banner-r::before{animation-delay:-2.4s}
/* a real candle-flame flicker: irregular steps, never a sine */
@keyframes fxTorch{
  0%  {opacity:.72;transform:scale(1)}
  12% {opacity:1;  transform:scale(1.05)}
  20% {opacity:.8}
  31% {opacity:.97;transform:scale(1.02)}
  44% {opacity:.68;transform:scale(.97)}
  55% {opacity:.93}
  68% {opacity:.76;transform:scale(1.03)}
  81% {opacity:1;  transform:scale(1.01)}
  92% {opacity:.79}
  100%{opacity:.72;transform:scale(1)}
}

/* the highlight that runs down the weave as the banner turns into the light */
.lux-banner::after{
  content:'';
  position:absolute;inset:0;
  pointer-events:none;
  background:linear-gradient(168deg,
    transparent 30%,
    rgba(255,246,222,.09) 43%,
    rgba(255,255,255,.15) 48%,
    rgba(255,238,196,.07) 53%,
    transparent 66%);
  background-size:100% 260%;
  background-repeat:no-repeat;
  animation:fxClothLight 11s ease-in-out infinite;
}
.lux-banner-r::after{animation-delay:-5.5s}
@keyframes fxClothLight{
  0%,100%{background-position:0 -60%}
  50%    {background-position:0 150%}
}

/* ══════════════════ 4. THE LOGIN PLATE — glass + candlelight ═════════════
   Both .lux-signin-bar pseudos carry `z-index:-1`. The bar is not a stacking
   context, so they escape up to .lux-signin (isolate) and land BETWEEN the
   plate (.lux-signin::before, also -1 but earlier in tree order) and the
   fields — i.e. sheen on the glass, under the content.                      */

.lux-signin-bar::before{
  content:'';
  position:absolute;z-index:-1;pointer-events:none;
  inset:-13px -20px;
  background:linear-gradient(103deg,
    transparent 32%,
    rgba(198,222,255,.05)  41%,
    rgba(255,250,232,.185) 49%,
    rgba(255,232,180,.06)  57%,
    transparent 66%);
  background-size:260% 100%;
  background-repeat:no-repeat;
  animation:fxPlateSheen 9s cubic-bezier(.5,0,.5,1) 1.6s infinite;
}
/* focus/hover: the glass lights up and the sweep quickens */
.lux-signin:hover .lux-signin-bar::before,
.lux-signin:focus-within .lux-signin-bar::before{
  animation-duration:3.6s;
  animation-delay:0s;
}

/* a warm inner bloom that only exists while the plate is being used */
.lux-signin-bar::after{
  content:'';
  position:absolute;z-index:-1;pointer-events:none;
  inset:-13px -20px;
  opacity:0;
  background:radial-gradient(70% 150% at 50% 50%, rgba(255,206,132,.13), transparent 72%);
  box-shadow:inset 0 0 34px rgba(255,204,128,.11),
             0 0 34px rgba(226,170,72,.17);
  transition:opacity .45s ease;
}
.lux-signin:hover .lux-signin-bar::after,
.lux-signin:focus-within .lux-signin-bar::after{opacity:1}

@keyframes fxPlateSheen{
  0%,58%{background-position:150% 0}
  92%,100%{background-position:-70% 0}
}

/* ── THE CANDLE ───────────────────────────────────────────────────────────
   A warm bloom that hangs around the plate and never stops flickering, so
   the sign-in reads as a lit desk rather than a floating rectangle. Hosted
   on the FORM: at z-index:-1 inside .lux-signin (isolate) it paints above
   .lux-signin::before (the plate itself, earlier in tree order) and below
   every field — candlelight falling ON the glass, spilling past its edges.
   `position:relative` on a form changes no geometry. */
.lux-signin-form{position:relative}
.lux-signin-form::before{
  content:'';
  position:absolute;z-index:-2;pointer-events:none;
  /* exactly the board's own box: login-luxe hands the geometry down as
     --pl-y / --pl-x, so the halo can never drift off the plate */
  inset:calc(-1 * var(--pl-y,14px)) calc(-1 * var(--pl-x,22px));
  /* a BOX-shadow, not a radial: the glow then follows the rectangle of the
     board instead of an ellipse that misses its corners on a 980px plate */
  box-shadow:
    0  0 58px 10px rgba(var(--wl-candle,255,196,120),.17),
    0 16px 96px  6px rgba(var(--wl-torch,255,162,74),.14);
  animation:fxCandle 5.6s ease-in-out infinite, fxWash 2.4s ease .8s both;
}
/* candle flicker — deliberately arrhythmic; a sine reads as a UI pulse */
@keyframes fxCandle{
  0%  {opacity:.86;transform:scale(1)}
  9%  {opacity:1;  transform:scale(1.018)}
  17% {opacity:.9}
  26% {opacity:.99;transform:scale(1.006)}
  38% {opacity:.82;transform:scale(.992)}
  49% {opacity:.96}
  61% {opacity:.88;transform:scale(1.012)}
  73% {opacity:1;  transform:scale(1.004)}
  86% {opacity:.9}
  100%{opacity:.86;transform:scale(1)}
}
/* using the plate turns the candle up */
.lux-signin:hover .lux-signin-form::before,
.lux-signin:focus-within .lux-signin-form::before{animation-duration:3.2s,2.4s}

/* ══════════════════ 5. FIELDS — a rune lights under the text ═════════════ */

/* login-luxe §6b owns ONE focus language page-wide: a gold hairline ring plus
   a warm 22px glow on `.field:focus-within`, and `--lux-gold-hi` outlines
   everywhere else. Everything below is drawn from that same ramp and sits
   INSIDE the field, so it extends that language instead of competing with it.
   .field is display:flex — both pseudos are absolutely positioned, so they
   are taken out of flow and never become flex items.

   TWO background layers: [0] is a short travelling glint that runs along the
   bar while the field is focused, [1] is the bar itself. Animating
   background-position on a 1px-tall strip is free. */
.field::before{
  content:'';
  position:absolute;z-index:1;pointer-events:none;
  left:0;right:0;bottom:-1px;height:1px;
  transform:scaleX(0);transform-origin:50% 50%;
  background-image:
    linear-gradient(90deg,transparent,rgba(255,252,240,.95) 44%,transparent),
    linear-gradient(90deg,transparent,
      rgba(238,206,142,.92) 22%, var(--lux-gold-hi,#fff5da) 50%,
      rgba(238,206,142,.92) 78%, transparent);
  background-size:34% 100%,100% 100%;
  background-repeat:no-repeat,no-repeat;
  background-position:-60% 0,0 0;
  box-shadow:0 0 10px rgba(214,158,64,.62);
  transition:transform .38s cubic-bezier(.2,.8,.3,1);
}
.field:focus-within::before{
  transform:scaleX(1);
  animation:fxRuneTravel 2.9s cubic-bezier(.5,0,.5,1) .34s infinite;
}
@keyframes fxRuneTravel{
  0%,10%  {background-position:-60% 0,0 0}
  70%,100%{background-position:160% 0,0 0}
}

/* a lit rim rather than a wash — the input text must stay untinted */
.field::after{
  content:'';
  position:absolute;z-index:0;pointer-events:none;
  inset:0;opacity:0;
  box-shadow:
    inset 0 0 0 1px rgba(238,206,142,.28),
    inset 0 0 22px rgba(214,158,64,.20);
  transition:opacity .3s ease;
}
.field:focus-within::after{opacity:1}
/* the icon on the left catches the same light */
.field:focus-within .f-ic{color:#ffe3ac;text-shadow:0 0 14px rgba(255,196,96,.6)}
.field.is-bad::before{
  background-image:linear-gradient(90deg,transparent,rgba(255,150,140,.95),transparent);
  background-size:100% 100%;
  background-position:0 0;
  box-shadow:0 0 10px rgba(224,90,80,.7);
  transform:scaleX(1);
  animation:none;
}

/* ENTRANCE — the runes ignite once as the plate arrives, then settle.
   No fill mode on purpose: when the animation ends the bar snaps back to its
   own `transform:scaleX(0)`, and :focus-within still owns it from then on. */
.lux-signin-bar .field::before{
  animation:fxRuneCharge 1.15s cubic-bezier(.3,.7,.3,1) 1.05s;
}
.lux-signin-bar .field:nth-of-type(2)::before{animation-delay:1.19s}
@keyframes fxRuneCharge{
  0%  {transform:scaleX(0)}
  38% {transform:scaleX(1)}
  62% {transform:scaleX(1)}
  100%{transform:scaleX(0)}
}
/* …but never fight a real focus */
.lux-signin-bar .field:focus-within::before{
  animation:fxRuneTravel 2.9s cubic-bezier(.5,0,.5,1) .34s infinite;
}

/* ══════════════════ 6. BUTTONS — press feel + a better sheen ═════════════
   wizloria.css sweeps .btn::after by animating `left`, which relayouts that
   pseudo every frame on four buttons forever. Same look, transform only.    */

.btn::after{
  left:0;width:46%;
  transform:translate3d(-230%,0,0) skewX(-18deg);
  animation:fxBtnSheen 5.5s ease-in-out infinite;
  will-change:transform;
}
@keyframes fxBtnSheen{
  0%,72%{transform:translate3d(-230%,0,0) skewX(-18deg)}
  92%,100%{transform:translate3d(330%,0,0) skewX(-18deg)}
}

/* a flash that blooms out of the middle of the button when it is pressed */
.btn::before{
  content:'';
  position:absolute;inset:0;z-index:2;
  pointer-events:none;opacity:0;
  background:radial-gradient(60% 120% at 50% 50%, rgba(255,246,222,.55), rgba(255,206,132,.18) 45%, transparent 76%);
}
.btn:active::before{animation:fxPress .42s ease-out}
@keyframes fxPress{
  from{opacity:.95;transform:scale(.82)}
  to  {opacity:0;transform:scale(1.12)}
}

/* The primary CTA breathes so the eye finds it without a colour change.
   The keyframe has to restate wizloria's drop shadow (a box-shadow animation
   replaces the property wholesale) — it is restated in login-luxe's night
   blue, never black, per the de-darkening pass. */
.lux-signin-go{
  animation:fxCtaPulse 4.6s ease-in-out 1.6s infinite;
}
@keyframes fxCtaPulse{
  0%,100%{box-shadow:0 6px 20px rgba(var(--lux-deep,3,7,18),.55), 0 0 0 rgba(226,170,72,0)}
  50%    {box-shadow:0 6px 20px rgba(var(--lux-deep,3,7,18),.55), 0 0 26px rgba(232,178,80,.42)}
}

/* HOVER = the button is CHARGED. Two things happen at once: a ring of light
   pushes out of its edge (box-shadow, one small element), and gold sparks
   start rising off the face.
   `isolation:isolate` makes .btn-face a stacking context so the spark layer's
   z-index:-1 stays inside it — painting above the face's own gradient and
   BELOW its label. Without that it would escape to .lux-signin and vanish
   behind the plate. isolation changes no geometry. */
.lux-signin-go:hover{animation:fxCtaCharged 1.9s ease-in-out infinite}
@keyframes fxCtaCharged{
  0%  {box-shadow:0 6px 20px rgba(var(--lux-deep,3,7,18),.55), 0 0 22px rgba(255,198,116,.50), 0 0 0 0 rgba(255,214,146,.40)}
  70% {box-shadow:0 6px 20px rgba(var(--lux-deep,3,7,18),.55), 0 0 40px rgba(255,206,132,.62), 0 0 0 13px rgba(255,214,146,0)}
  100%{box-shadow:0 6px 20px rgba(var(--lux-deep,3,7,18),.55), 0 0 22px rgba(255,198,116,.50), 0 0 0 0 rgba(255,214,146,0)}
}

/* ⛔ MEASURED, and it cost an iteration: PALE sparks on this button are
   invisible. `.btn-gold .btn-face` is #f7e2ab → #c48f34, i.e. already near
   white at the top, so 1.5px dots of rgba(255,250,226,.95) vanished
   completely at 3x zoom. Every ember below is therefore a BRIGHT CORE INSIDE
   A DARK AMBER HALO — the halo carries it over the pale top of the face, the
   core carries it over the dark lower band. Same trick a game engine uses for
   sparks over a variable background. */
.lux-signin-go .btn-face{isolation:isolate}
.lux-signin-go .btn-face::after{
  content:'';
  position:absolute;z-index:-1;pointer-events:none;
  left:0;right:0;top:-70px;bottom:0;
  opacity:0;
  background-repeat:repeat;
  background-size:70px 70px;
  background-image:
    radial-gradient(circle 2.6px at 11px 20px, rgba(255,252,238,.95), rgba(176,92,14,.60) 46%, transparent 100%),
    radial-gradient(circle 2.0px at 47px 51px, rgba(255,246,214,.92), rgba(158,80,10,.55) 48%, transparent 100%),
    radial-gradient(circle 3.0px at 31px  8px, rgba(255,250,230,.88), rgba(186,100,18,.52) 44%, transparent 100%),
    radial-gradient(circle 2.2px at 60px 33px, rgba(255,240,196,.90), rgba(168,86,12,.58) 46%, transparent 100%),
    radial-gradient(circle 1.8px at 20px 62px, rgba(255,248,222,.85), rgba(150,74,10,.52) 50%, transparent 100%);
  transition:opacity .28s ease;
}
.lux-signin-go:hover .btn-face::after,
.lux-signin-go:focus-visible .btn-face::after{
  opacity:.95;
  animation:fxSparkRise 2.3s linear infinite;
}
@keyframes fxSparkRise{
  from{transform:translate3d(0,0,0)}
  to  {transform:translate3d(0,-70px,0)}
}
/* the gold keeps catching light while it is charged, and the label lights
   with it. `.btn-gold .btn-face` owns a text-shadow, so this restates it. */
.lux-signin-go:hover::after{animation-duration:1.5s}
.lux-signin-go:hover .btn-face{
  text-shadow:0 1px 0 rgba(255,246,216,.75), 0 0 13px rgba(255,232,180,.85);
}

/* the small round controls pick up a gold halo on hover.
   .soc already transitions filter, and .lux-arrow / .lux-auth-x carry their
   own multi-property transition lists — redeclaring `transition` on those
   would silently drop the properties they animate, so only .f-eye is
   extended, and only by adding filter to what it already had. */
.f-eye{transition:color .18s ease,filter .22s ease}
.soc:hover,.f-eye:hover{filter:drop-shadow(0 0 10px rgba(232,182,88,.65))}
.lux-arrow:hover{filter:drop-shadow(0 0 12px rgba(238,196,110,.55))}

/* ══════════════════ 7. GOLD RULES — a slow shimmer ═══════════════════════
   opacity + filter only: the geometry and the gradients stay login-luxe's.  */

.lux-hp::before,.lux-hp::after,
.lux-select-label i,
.lux-signin-rule{
  animation:fxRule 7.5s ease-in-out infinite;
}
.lux-hp::after{animation-delay:-3.75s}
.lux-select-label i:last-child{animation-delay:-3.75s}
.lux-signin-rule{animation-delay:-2s}
@keyframes fxRule{
  0%,100%{opacity:.72;filter:none}
  50%    {opacity:1;filter:drop-shadow(0 0 6px rgba(240,206,140,.75))}
}

/* The section label's own glow answers the rules — as a `filter`, NOT as a
   text-shadow. login-luxe buys that line's legibility on the bright gatehouse
   with a tight 5-stop halo; animating `text-shadow` here would REPLACE the
   whole stack every frame and throw the halo away. drop-shadow composes over
   it instead, so the legibility stack is untouched. */
.lux-select-label span{animation:fxLabel 7.5s ease-in-out infinite}
@keyframes fxLabel{
  0%,100%{filter:drop-shadow(0 0 4px rgba(226,178,88,.10))}
  50%    {filter:drop-shadow(0 0 9px rgba(255,206,124,.45))}
}

/* ══════════════════ 8. CHARACTER CARDS ══════════════════════════════════ */

/* the card needs a containing block for its bloom; position only, no box
   change, so nothing about the rail's layout moves */
.lux-char{position:relative}

/* ── CONTACT SHADOW — the one piece of dark ink in this file ──────────────
   Without it the roster floats: eleven cut-outs hanging in the air over the
   ground plane. This is a ~30px ellipse pinned to the BOTTOM EDGE OF THE ART
   (top = var(--art-h), the exact height login-luxe gives .lux-char-art), so
   it lands on the ground whatever the viewport does to the card size.
   The blur is baked into the gradient stops — filter:blur() here would mean
   eleven filter passes on a horizontally scrolling rail.
   z-index:-1 puts it in .lux-select's negative layer, which the painting
   algorithm draws before ANY card content, so every portrait sits on top of
   every shadow. On :hover login-luxe gives .lux-char `z-index:2`, which traps
   the pseudo inside the card — same result, one card deep.
   ⚠ left/right stay at 0. A negative horizontal inset here would spill past
   the LAST card and add to `#luxRoster`'s scrollWidth — which is how a rail
   that fits suddenly grows arrows. The card box is already 18px wider than
   the art, so there is room for the ellipse inside it.
   The third stop is the ground catching the light back: on the grass the
   shadow alone read as a hole punched in the turf. */
.lux-char::before{
  content:'';
  position:absolute;z-index:-1;pointer-events:none;
  left:0;right:0;
  top:calc(var(--art-h,132px) - 7px);
  height:38px;
  background:
    radial-gradient(41% 42% at 50% 24%, rgba(3,8,20,.78), rgba(3,8,20,.36) 50%, transparent 78%),
    radial-gradient(76% 32% at 50% 26%, rgba(4,10,24,.36), transparent 76%),
    radial-gradient(58% 52% at 50% 84%, rgba(var(--wl-torch,255,162,74),.12), transparent 74%);
  transition:opacity .3s ease,transform .34s cubic-bezier(.2,.8,.3,1);
}
/* lifted card → the contact patch spreads and softens, which is what sells
   the lift more than the translate does.
   ⚠ The shadow is INSIDE .lux-char, so login-luxe's hover
   `translateY(-7px) scale(1.13)` about `transform-origin:50% 92%` drags it up
   with the card — roughly 12px at the shadow's own height. The +13px here is
   that debt paid back, not a stylistic offset: without it the shadow climbs
   into the portrait and the card reads as glued to its own shadow. */
.lux-char:hover::before,
.lux-char:focus-visible::before{
  opacity:.5;
  transform:translateY(13px) scale(1.26,.78);
}

/* HOUSE BLOOM — sits behind the card art. `inset` keeps the element inside
   the card's own box (so the horizontally scrollable rail gains no width);
   the blur bleeds visually, and filter bleed is not scrollable overflow. */
.lux-char::after{
  content:'';
  position:absolute;z-index:-1;pointer-events:none;
  inset:6% 2% 12%;
  border-radius:14px;
  opacity:0;
  background:radial-gradient(62% 56% at 50% 46%,
    color-mix(in srgb, var(--hx,#26467f) 78%, #ffdca0) 0%,
    color-mix(in srgb, var(--hx,#26467f) 42%, transparent) 52%,
    transparent 78%);
  filter:blur(17px);
  transition:opacity .34s ease;
}
.lux-char:hover::after,
.lux-char:focus-visible::after{opacity:.9}

/* GLASS SHEEN over the portrait. .lux-char-art already has overflow:hidden,
   so the band is clipped to the frame with no extra containers. z:2 keeps it
   under WIZART's ornate rim (img.wlart-card, z:3). */
.lux-char-art::before{
  content:'';
  position:absolute;z-index:2;pointer-events:none;
  top:-20%;bottom:-20%;left:0;width:52%;
  background:linear-gradient(100deg,transparent,rgba(255,246,222,.30) 46%,rgba(255,255,255,.42) 52%,transparent);
  transform:translate3d(-220%,0,0) skewX(-16deg);
  opacity:0;
}
.lux-char:hover .lux-char-art::before,
.lux-char:focus-visible .lux-char-art::before{
  animation:fxCardSheen .92s cubic-bezier(.35,.7,.4,1);
}
@keyframes fxCardSheen{
  from{opacity:0;transform:translate3d(-220%,0,0) skewX(-16deg)}
  18% {opacity:1}
  82% {opacity:1}
  to  {opacity:0;transform:translate3d(320%,0,0) skewX(-16deg)}
}

/* the name lights with the card — a filter, so login-luxe's legibility
   text-shadow stack survives untouched */
.lux-char:hover .lux-char-name,
.lux-char:focus-visible .lux-char-name{
  filter:drop-shadow(0 0 9px rgba(255,214,142,.55));
}

/* the chosen one flares while the gates open */
.lux-roster.is-picked .lux-char.is-going::after{
  opacity:1;
  animation:fxChosen 1.1s ease-in-out infinite;
}
@keyframes fxChosen{
  0%,100%{opacity:.8;filter:blur(17px)}
  50%    {opacity:1;filter:blur(24px)}
}

/* ENTRANCE — login-luxe already rises .lux-select as a block, so the cards
   themselves are still free. `animation-fill-mode:backwards` is deliberate:
   `both` would leave the animation filling `transform` forever and silently
   beat the :hover transform.

   The stagger is carried by a CUSTOM PROPERTY inside the shorthand, not by a
   separate `animation-delay` — see the trap below: the moment this element
   has TWO animations, a lone `animation-delay:.56s` would delay both of them.
*/
.lux-char{
  --fx-deal-delay:.56s;
  animation:fxDeal .62s cubic-bezier(.2,.8,.3,1) var(--fx-deal-delay) backwards;
}
.lux-char:nth-child(2) {--fx-deal-delay:.61s}
.lux-char:nth-child(3) {--fx-deal-delay:.66s}
.lux-char:nth-child(4) {--fx-deal-delay:.71s}
.lux-char:nth-child(5) {--fx-deal-delay:.76s}
.lux-char:nth-child(6) {--fx-deal-delay:.81s}
.lux-char:nth-child(7) {--fx-deal-delay:.86s}
.lux-char:nth-child(8) {--fx-deal-delay:.91s}
.lux-char:nth-child(9) {--fx-deal-delay:.96s}
.lux-char:nth-child(10){--fx-deal-delay:1.01s}
.lux-char:nth-child(11){--fx-deal-delay:1.06s}
.lux-char:nth-child(12){--fx-deal-delay:1.11s}
@keyframes fxDeal{
  from{opacity:0;transform:translateY(13px) scale(.94)}
  to  {opacity:1;transform:none}
}

/* ⛔ CROSS-FILE TRAP — MEASURED ON THE LIVE BUILD, AND THIS RULE IS THE CURE.
   login-cards.js injects `.lux-char.lc-attract{animation:lcAttract 1.5s … both}`
   for its idle "attract" nudge. `animation` is ONE property, so that replaces
   the whole list: fxDeal leaves the list while the class is on, and when the
   class comes off fxDeal is matched as a BRAND NEW animation — 560-1110ms of
   `backwards` fill at opacity:0, then another 620ms fade. Every attract cycle
   therefore made a card blink out of the rail. Caught here as "card 3 is
   simply missing" in a 1600x900 capture (probe4: `rowan op=0 fxDeal:running`
   while every other card had no animations left at all).

   CSS matches running animations by NAME **and POSITION IN THE LIST**, so the
   fix is to keep fxDeal in slot 1 in BOTH states. Then adding/removing
   `.lc-attract` only appends/removes a second animation and fxDeal is never
   restarted. Specificity (0,3,0) here beats login-cards.js's (0,2,0) whatever
   order the injected <style> lands in.
   ⚠ This restates login-cards.js's own timing. If agent 9 retunes lcAttract,
   this line is the copy that has to follow — or delete it and re-solve the
   restart another way. Their reduced-motion `animation:none!important` still
   wins over this, so nothing here re-enables motion. */
.lux-roster .lux-char.lc-attract{
  animation:fxDeal .62s cubic-bezier(.2,.8,.3,1) var(--fx-deal-delay) backwards,
            lcAttract 1.5s cubic-bezier(.3,.7,.3,1) both;
}

/* ══════════════════ 9. THE OVERLAY CARD (email sign-up) ══════════════════ */

/* light behind the card instead of more shadow under it */
.lux-auth-veil::after{
  content:'';
  position:absolute;inset:0;pointer-events:none;
  mix-blend-mode:screen;
  background:
    radial-gradient(30% 34% at 50% 8%,  rgba(255,214,150,.15), transparent 72%),
    radial-gradient(46% 42% at 50% 34%, rgba(120,164,240,.11), transparent 74%);
  animation:fxWash .6s ease both, fxBreathe 9s ease-in-out 1s infinite;
}

/* a slow specular sweep across the card face, behind the form's content */
.lux-auth-card .form{position:relative}
/* right/bottom stay at 0: .lux-view is the scroll container, and any bleed
   past its padding box on those two edges would give the card a scrollbar */
.lux-auth-card .form::before{
  content:'';
  position:absolute;z-index:-1;pointer-events:none;
  top:-26px;left:-20px;right:0;bottom:0;
  background:linear-gradient(107deg,
    transparent 34%,
    rgba(255,243,214,.05) 44%,
    rgba(255,251,236,.12) 50%,
    rgba(255,243,214,.05) 56%,
    transparent 66%);
  background-size:250% 100%;
  background-repeat:no-repeat;
  animation:fxPlateSheen 8s cubic-bezier(.5,0,.5,1) 1s infinite;
}

/* the wax seals keep a soft halo (both hosts are z-indexed, so the ::after is
   trapped inside them and paints behind the seal art) */
.lux-signin-seal::after,
.lux-auth-card .wl-seal::after{
  content:'';
  position:absolute;inset:-42%;z-index:-1;
  pointer-events:none;
  border-radius:50%;
  background:radial-gradient(circle, rgba(255,196,110,.34), rgba(226,150,60,.12) 46%, transparent 72%);
  animation:fxSeal 5.5s ease-in-out infinite;
}
@keyframes fxSeal{
  0%,100%{opacity:.55;transform:scale(.94)}
  50%    {opacity:1;transform:scale(1.06)}
}

/* the sign-in seal is STAMPED onto the plate as the page settles.
   login-luxe centres it with `transform:translate(-52%,-56%)`, so every
   keyframe here has to carry that translate or the seal jumps off the edge. */
.lux-signin-seal{
  animation:fxStamp .66s cubic-bezier(.22,1.24,.4,1) .82s backwards;
}
@keyframes fxStamp{
  0%  {opacity:0;transform:translate(-52%,-56%) scale(1.9) rotate(-13deg)}
  55% {opacity:1}
  100%{opacity:1;transform:translate(-52%,-56%) scale(1) rotate(0)}
}

/* ══════════════════ 10. TOP BAR + FOOTER polish ═════════════════════════ */

.lux-loginbtn{position:relative;overflow:hidden}
.lux-loginbtn::after{
  content:'';
  position:absolute;top:0;bottom:0;left:0;width:44%;
  pointer-events:none;
  background:linear-gradient(100deg,transparent,rgba(255,246,222,.26),transparent);
  transform:translate3d(-230%,0,0) skewX(-18deg);
  animation:fxBtnSheen 7s ease-in-out 2.2s infinite;
}
.lux-loginbtn:hover::after{animation-duration:2.6s}
/* the footer's own legibility shadow is inherited from .lux-foot, so the hover
   glow has to RESTATE it — a bare text-shadow here would drop it */
.lux-foot a{position:relative}
.lux-foot a:hover{
  text-shadow:0 1px 2px rgba(var(--lux-deep,3,7,18),.8), 0 0 12px rgba(232,182,88,.6);
}

/* ══════════════════ 11. SMALL SCREENS ═══════════════════════════════════
   Only effect geometry is touched here — never layout.                      */

@media (max-width:900px){
  /* login-luxe flushes the plate to the rail at this width, so the sheen
     must stop overhanging it sideways */
  .lux-signin-bar::before,
  .lux-signin-bar::after{inset:-13px 0}
  .lux-signin-form::before{inset:-30px -14px -22px}
}

@media (max-width:760px){
  /* phones: one mote field only — fill rate and battery. The ember tile keeps
     its 270px size because fxEmberRise translates by exactly one tile; change
     one and the loop stops being seamless. The rake and the near field are
     the two most expensive layers (a mask and a 330px tile), so both go. */
  .lux-air::before{display:none}
  body.luxe::before,
  body.luxe::after{display:none}
  .lux-stage::after{opacity:.42}
  .lux-char::after{filter:blur(13px)}
  .lux-char::before{height:24px;top:calc(var(--art-h,116px) - 5px)}
}

/* coarse pointers never hover — do not pay for the card sheen there */
@media (hover:none){
  .lux-char-art::before{display:none}
  .lux-signin-bar::after{opacity:0}
  .lux-signin-go .btn-face::after{display:none}
}

/* ══════════════════ 12. REDUCED MOTION — everything freezes ══════════════ */

@media (prefers-reduced-motion:reduce){
  body.luxe::before,body.luxe::after,
  .scene-grade::before,
  .lux-stage::before,.lux-stage::after,
  .lux-air::before,.lux-air::after,
  .lux-banner,.lux-banner img,.lux-banner::before,.lux-banner::after,
  .lux-signin-bar::before,.lux-signin-bar::after,
  .lux-signin-form::before,
  .lux-signin:hover .lux-signin-form::before,
  .lux-signin:focus-within .lux-signin-form::before,
  .lux-signin-go,.lux-signin-go:hover,.lux-loginbtn::after,
  .lux-signin-go .btn-face::after,
  .lux-signin-go:hover .btn-face::after,
  .btn::before,.btn::after,
  .lux-hp::before,.lux-hp::after,.lux-select-label i,.lux-select-label span,
  .lux-signin-rule,.lux-char,.lux-roster .lux-char.lc-attract,
  .lux-char::before,.lux-char::after,.lux-char-art::before,
  .lux-signin-bar .field::before,
  .lux-signin-bar .field:focus-within::before,
  .field:focus-within::before,
  .lux-signin-seal,
  .lux-auth-veil::after,.lux-auth-card .form::before,
  .lux-signin-seal::after,.lux-auth-card .wl-seal::after,
  .lux-roster.is-picked .lux-char.is-going::after{
    animation:none!important;
  }
  /* the sweeps park off-stage instead of freezing mid-screen */
  .btn::after,.lux-loginbtn::after{transform:translate3d(-230%,0,0) skewX(-18deg)}
  .lux-char-art::before{opacity:0}
  .lux-char{opacity:1;transform:none}
  .lux-banner img{opacity:1;transform:none}
  .lux-signin-seal{opacity:1;transform:translate(-52%,-56%)}
  .field::before,.field::after,.lux-char::before,.lux-char::after,
  .lux-signin-bar::after{
    transition:none!important;
  }
}
