/* Portable wrapper: .rfx > .rfx-content + .rfx-layer. Set data-effect and --rfx-color. */
.rfx{--rfx-color:#91a8c9;--rfx-intensity:.75;position:relative;isolation:isolate;display:inline-grid;place-items:center;width:94px;height:94px;border-radius:50%;background:#171d26;box-shadow:0 8px 16px #0005}
.rfx-content{position:relative;width:100%;height:100%;border-radius:inherit;display:grid;place-items:center;z-index:1;overflow:hidden}
.rfx-layer{position:absolute;inset:0;z-index:2;border-radius:inherit;pointer-events:none;opacity:var(--rfx-intensity)}
/* An effect lives round what wears it, and is free to go past it: tentacles off a card, flames above it, a halo round
   a medal. What it must know is where the thing really ends (issue #871): its outline is its visible pixels, not the
   box it is drawn in. So nothing here clips an effect. A shader is handed the outline instead and builds round it (a
   cut-out card's artwork, a medal's body: `card-silhouette.js`), and the layer drawn in CSS, which paints on the
   thing rather than round it, is masked by that same outline so it never fills the empty part of the box. */
.card-art > .card-rarity-effect > .rfx-layer,.rfx.badge-rarity-effect > .rfx-layer,.rfx[data-outline] > .rfx-layer{mask-image:var(--rfx-image-mask,none);mask-size:contain;mask-position:center;mask-repeat:no-repeat;-webkit-mask-image:var(--rfx-image-mask,none);-webkit-mask-size:contain;-webkit-mask-position:center;-webkit-mask-repeat:no-repeat}
.rfx-layer::before,.rfx-layer::after{content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none}
.rfx[data-shape=card]{width:108px;height:146px;border-radius:10px;border:3px solid #b69c70}
/* Unique keeps its pink-and-cyan identity, with a visibly circulating energy rim. */
.rfx[data-effect=unique-energy] { --rfx-intensity: 1; }
.rfx[data-effect=unique-energy] > .rfx-layer {
    box-shadow: 0 0 2px 1px #a1fffa, 0 0 18px #ff3cac99, inset 0 0 8px #4deeea55;
    animation: rfx-unique-pulse 5.2s ease-in-out infinite;
}
.rfx[data-effect=unique-energy] > .rfx-layer::before {
    inset: -2px; padding: 2px;
    background: linear-gradient(115deg, #ff3cac 5%, #ff8acd 22%, #fff1ff 29%, #4deeea 36%, #a1fffa 57%, #fff1ff 65%, #ff3cac 74%);
    background-size: 300% 100%;
    mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
    mask-composite: exclude;
    animation: rfx-unique-circuit 6.4s linear infinite;
}
.rfx[data-effect=unique-energy] > .rfx-layer::after {
    inset: -10px;
    background:
        radial-gradient(ellipse 2px 17px at 15% 5%, #fff0ff 15%, #ff8acdaa 35%, transparent 70%),
        radial-gradient(ellipse 17px 2px at 15% 5%, #fff0ff 15%, #ff8acdaa 35%, transparent 70%),
        radial-gradient(ellipse 2px 20px at 94% 73%, #a1fffa 15%, #4deeeaaa 35%, transparent 70%),
        radial-gradient(ellipse 20px 2px at 94% 73%, #a1fffa 15%, #4deeeaaa 35%, transparent 70%),
        radial-gradient(circle at 7% 64%, #a1fffa 0 1px, transparent 3px),
        radial-gradient(circle at 76% 95%, #ff8acd 0 2px, transparent 4px);
    animation: rfx-energy-sparks 5.2s ease-in-out infinite;
}
@keyframes rfx-energy-flow { 0%, 100% { background-position: 0% 20%; } 50% { background-position: 100% 80%; } }
@keyframes rfx-energy-sparks { 0%, 100% { opacity: .25; transform: translateY(5px); } 50% { opacity: 1; transform: translateY(-5px); } }
@keyframes rfx-unique-circuit { from { background-position: 150% 50%; } to { background-position: -150% 50%; } }
@keyframes rfx-unique-pulse { 0%, 100% { box-shadow: 0 0 2px 1px #a1fffa, 0 0 11px #ff3cac66, inset 0 0 5px #4deeea33; } 50% { box-shadow: 0 0 3px 1px #fff0ff, 0 0 24px #ff3cacbb, inset 0 0 10px #4deeea55; } }
.rfx[data-effect=satin] .rfx-layer{background:linear-gradient(125deg,#fff4,transparent 40%,#0003)}
.rfx[data-effect=etched] .rfx-layer{inset:5px;border:1px dashed #fff9;box-shadow:0 0 0 2px #0003}
.rfx[data-effect=breath] .rfx-layer{box-shadow:0 0 17px var(--rfx-color);animation:rfx-breathe 4s ease-in-out infinite}
.rfx[data-effect=glint] .rfx-layer{background:linear-gradient(115deg,transparent 30%,#fff8 49%,transparent 65%);background-size:300% 100%;animation:rfx-sweep 5s ease-in-out infinite}
.rfx[data-effect=halo] .rfx-layer{inset:-5px;border:1px solid var(--rfx-color);box-shadow:0 0 13px var(--rfx-color),inset 0 0 8px var(--rfx-color)}
.rfx[data-effect=dew] .rfx-layer{background:radial-gradient(circle at 22% 25%,#fff 0 1px,transparent 2px),radial-gradient(circle at 80% 60%,#fff 0 2px,transparent 3px),radial-gradient(circle at 34% 86%,#fff 0 1px,transparent 3px);animation:rfx-breathe 3s infinite}
.rfx[data-effect=orbit] .rfx-layer{inset:-9px;border:1px solid #ffffff20;animation:rfx-spin 7s linear infinite}
.rfx[data-effect=orbit] .rfx-layer::before{inset:-3px auto auto 50%;width:6px;height:6px;background:#ceffe5;box-shadow:0 0 10px var(--rfx-color)}
.rfx[data-effect=scan] .rfx-layer{background:linear-gradient(transparent 40%,#adffd270 50%,transparent 60%);background-size:100% 300%;animation:rfx-scan 4s ease-in-out infinite}
.rfx[data-effect=chrome] .rfx-layer{background:linear-gradient(130deg,transparent 20%,#b5d8ff99 30%,#fff9 32%,transparent 38%,#82b9ff60 70%,transparent 80%);background-size:250% 100%;animation:rfx-sweep 5s infinite}
.rfx[data-effect=ripple] .rfx-layer::before,.rfx[data-effect=ripple] .rfx-layer::after{border:1px solid var(--rfx-color);animation:rfx-ripple 3.5s ease-out infinite}
.rfx[data-effect=ripple] .rfx-layer::after{animation-delay:-1.75s}
.rfx[data-effect=frost] .rfx-layer{background:repeating-conic-gradient(from 20deg,#e0f5ff80 0 1deg,transparent 1deg 30deg);box-shadow:inset 0 0 20px #b9e6ff,0 0 10px #82c6ff80;animation:rfx-breathe 5s infinite}
.rfx[data-effect=twinkle] .rfx-layer::before{inset:-8px;background:radial-gradient(ellipse at 18% 24%,white 0 2px,transparent 3px),radial-gradient(ellipse at 80% 75%,white 0 2px,transparent 3px);filter:drop-shadow(0 0 4px #b6d7ff);animation:rfx-breathe 2s infinite}
.rfx[data-effect=twinkle] .rfx-layer::after{inset:-10px;background:radial-gradient(ellipse at 85% 10%,white 0 1px,transparent 3px);animation:rfx-breathe 3s infinite reverse}
.rfx[data-effect=plasma] .rfx-layer{inset:-5px;border:2px dotted #ddadff;box-shadow:0 0 15px #b565ee,inset 0 0 10px #bd78ec;animation:rfx-breathe 1.8s infinite}
.rfx[data-effect=orbitals] .rfx-layer::before,.rfx[data-effect=orbitals] .rfx-layer::after{inset:-14px;border:1px solid #dfaaff;transform:rotate(-30deg) scaleX(.6);animation:rfx-orbital 6s linear infinite}
.rfx[data-effect=orbitals] .rfx-layer::after{animation-delay:-3s;animation-direction:reverse}
.rfx[data-effect=velvet] .rfx-layer{background:repeating-linear-gradient(140deg,transparent 0 7px,#e6adff60 8px,transparent 10px);background-size:200% 100%;mix-blend-mode:screen;animation:rfx-sweep 8s infinite}
.rfx[data-effect=gilded] .rfx-layer{background:linear-gradient(110deg,transparent 20%,#ffb80055 40%,#fff4bcdd 50%,#f7b60055 60%,transparent 80%);background-size:300% 100%;animation:rfx-sweep 4s infinite;box-shadow:0 0 15px #ffc75a60}
.rfx[data-effect=embers] .rfx-layer::before{inset:-20px;background:radial-gradient(circle at 20% 85%,#ffc260 0 2px,transparent 3px),radial-gradient(circle at 80% 60%,#ffedb0 0 1px,transparent 2px),radial-gradient(circle at 65% 90%,#ff973e 0 2px,transparent 3px);animation:rfx-rise 3s linear infinite}
.rfx[data-effect=embers] .rfx-layer::after{inset:-15px;background:radial-gradient(circle at 30% 75%,#ffe8a0 0 1px,transparent 3px),radial-gradient(circle at 90% 80%,#ffb14f 0 2px,transparent 3px);animation:rfx-rise 3s -1.5s linear infinite}
.rfx[data-effect=corona] .rfx-layer{inset:-12px;z-index:-1;background:repeating-conic-gradient(#ffc86b90 0 3deg,transparent 4deg 18deg);filter:blur(3px);animation:rfx-spin 30s linear infinite;box-shadow:0 0 30px #f5b54170}
.rfx[data-effect=divine] .rfx-layer::before{inset:-8px;border:1px solid #ffe6a9;box-shadow:0 0 0 5px #ffc75c15,0 0 0 9px #ffc75c55,0 0 25px #ffc75c80;animation:rfx-breathe 4s infinite}
.rfx[data-effect=prism] .rfx-layer{background:linear-gradient(120deg,#ff609970,#ffc65b70,#77ffbd70,#55baff70,#c57dff70,#ff609970);background-size:400% 100%;mix-blend-mode:screen;animation:rfx-sweep 5s infinite}
.rfx[data-effect=singularity] .rfx-layer{inset:-9px;z-index:-1;background:conic-gradient(#ff99d6,transparent 30%,#889bff,transparent 70%,#ff99d6);box-shadow:0 0 24px #cd77ca90;animation:rfx-spin 4s linear infinite}
.rfx[data-effect=iridescent] .rfx-layer{background:repeating-conic-gradient(from 45deg,#ffaed880 0deg,#b7ffff80 50deg,#ffeab880 100deg,#b8a7ff80 150deg,#ffaed880 180deg);background-size:200% 200%;mix-blend-mode:screen;animation:rfx-pearl 7s ease-in-out infinite}
@keyframes rfx-sweep{0%,100%{background-position:100% 50%}50%{background-position:0% 50%}}
@keyframes rfx-scan{0%,100%{background-position:50% 100%}50%{background-position:50% 0%}}
@keyframes rfx-breathe{0%,100%{opacity:calc(var(--rfx-intensity) * .2)}50%{opacity:var(--rfx-intensity)}}
@keyframes rfx-spin{to{transform:rotate(360deg)}}
@keyframes rfx-ripple{0%{transform:scale(1);opacity:.8}100%{transform:scale(1.45);opacity:0}}
@keyframes rfx-orbital{from{transform:rotate(0deg) scaleX(.65)}to{transform:rotate(360deg) scaleX(.65)}}
@keyframes rfx-rise{from{transform:translateY(12px);opacity:0}35%{opacity:1}to{transform:translateY(-45px);opacity:0}}
@keyframes rfx-pearl{0%,100%{background-position:0% 20%}50%{background-position:100% 80%}}
.rfx-paused .rfx-layer,.rfx-paused .rfx-layer::before,.rfx-paused .rfx-layer::after{animation-play-state:paused!important}
/* Set by rfx-visibility.js on an effect out of view: a running light repaints the page each frame. */
.rfx-offscreen .rfx-layer,.rfx-offscreen .rfx-layer::before,.rfx-offscreen .rfx-layer::after{animation-play-state:paused!important}
.motion-reduced .rfx-layer,.motion-reduced .rfx-layer::before,.motion-reduced .rfx-layer::after{animation:none!important}


/* Transparent procedural fire mounted by rarity-fire.js. Celestial and
   mythical are shaded surfaces instead; they carry no CSS of their own. */
.rfx[data-effect=violet-flames] .rfx-layer { inset:0; z-index:-1; }
.rfx[data-effect=violet-flames] .rfx-layer::before { box-shadow:0 0 7px #b264ed80,0 0 15px #8f37c830; }
.rfx-fire { position:absolute;width:calc(100% + 80px);height:calc(100% + 100px);left:-40px;bottom:-30px;pointer-events:none; }

/* Badge integration: retain the original medal's size and material. */
/* The medal keeps its own size and material; the effect is an overlay on it. */
/* The host takes the medal's own size rather than imposing one: a `.badge-medal`
   already has a box, so forcing 100% onto it shrank it. Only a bare medal SVG
   needs a size, and it is the surrounding context that knows which. */
.badge-effect-host { position:relative;display:inline-block;vertical-align:middle;flex:none;line-height:0; }
.badge-effect-host > .badge-medal { display:grid;box-sizing:border-box; }
.badge-effect-host > svg { display:block;width:64px;height:64px; }
.badge-mount .badge-effect-host > svg { width:83px;height:83px; }
/* Overlaying only makes sense inside the host that positions it: loose in a
   page, an absolute `.rfx` would stretch over whatever it landed in. */
/* The host's box is the medal's, and the effect lies over the medal's body in it: the square round the disc, the star
   or the cross, centred a little low (badge-cabinet.js, `badgeMedalSilhouette`), which badge-effects.js places, so
   an effect's own centre and edge are the body's. It is not cut: it goes past the medal as it goes past a card. */
.badge-effect-host > .rfx.badge-rarity-effect { position:absolute;inset:0;z-index:2;width:auto;height:auto;background:transparent;box-shadow:none;pointer-events:none; }
.rfx.badge-rarity-effect > .rfx-layer { z-index:0; }
/* Any object's finishes (`Objects.dress`, objects.js) lie in one layer over it, or over the part of it its type
   names: the foil sheet, the prismatic film and the rarity effect. The layer takes the object's form when it is
   not its box (`data-form`), and nothing clips an effect, which goes past the object as it goes past a card.
   A print (a card, a bill, a ticket) lays the same hosts inside its own layers instead. */
:where([data-object]) { position:relative; }
.object-finishes { position:absolute;inset:0;z-index:5;border-radius:inherit;pointer-events:none;rotate:none; }
.object-finishes[data-form=disc] { border-radius:50%; }
.object-finishes > .card-foil { border-radius:inherit; }
.is-negative-object { filter:invert(1); }
.rfx.object-rarity-effect { position:absolute;inset:0;z-index:1;width:auto;height:auto;border-radius:inherit;background:transparent;box-shadow:none;overflow:visible;pointer-events:none; }
.rfx.object-rarity-effect > .rfx-layer { z-index:0; }
.rfx.object-rarity-effect[data-effect=prismatic] { isolation:auto;mix-blend-mode:hard-light; }
.rfx.object-rarity-effect[data-effect=prismatic] > .prismatic-surface { mix-blend-mode:normal; }
/* A named form is the box's own, stretched with it: a disc on a square, an oval on anything else. */
.rfx[data-outline] > .rfx-layer { mask-size:100% 100%;-webkit-mask-size:100% 100%; }
.rfx.badge-rarity-effect[data-effect=prismatic] { isolation:auto;mix-blend-mode:hard-light; }
.rfx.badge-rarity-effect[data-effect=prismatic] > .prismatic-surface { mix-blend-mode:normal; }

/* A notification (a toast, an entry's icon) burns under its words: the host
   fills it and sits beneath its content, inside the stacking context the
   notification makes for it. */
.rfx.notification-rarity-effect { position:absolute;inset:0;z-index:-1;display:block;width:auto;height:auto;border-radius:inherit;background:transparent;box-shadow:none;pointer-events:none; }

/* Shaded surfaces overflow whatever they wrap — a card, a badge, a cut-out
   subject — so the canvas is centred on it and given room on every side. */
/* A finish sits on the print rather than around it, so the canvas covers the
   host exactly and hard-light lets it both screen and multiply what is under
   it: an additive overlay could only ever fog a light print.

   Where the blend goes depends on what it has to reach. A badge wraps its own
   medal, so the canvas blends inside the wrapper. A card's effect host is
   absolutely positioned with a z-index, which makes it a stacking context and
   therefore a blending boundary — a canvas inside it would have nothing to
   blend with, so the host itself carries the blend and reaches the print. */
.prismatic-surface { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.rfx[data-effect=prismatic] > .prismatic-surface { mix-blend-mode: hard-light; }
.trading-card .card-rarity-effect[data-effect=prismatic] { isolation: auto; mix-blend-mode: hard-light; }
.trading-card .card-rarity-effect[data-effect=prismatic] > .prismatic-surface { mix-blend-mode: normal; }
.rfx[data-prismatic-ready] > .rfx-layer { display: none; }
/* The light a Prismatic card throws round itself: a canvas of its own, wider than the card, like the
   surfaces below. It is outside the card, where there is nothing for the finish to blend with. */
.prismatic-aura {
    position: absolute; left: 50%; top: 50%;
    width: calc(100% / .62); height: calc(100% / .62);
    transform: translate(-50%, -50%);
    pointer-events: none;
}
.rfx[data-prismatic-spill] { overflow: visible; }

.celestial-surface, .mythical-surface, .gilded-surface, .abyssal-surface, .overgrown-surface, .ink-surface,
.stormforged-surface, .blueprint-surface, .deep-fried-surface, .unique-surface, .glitch-surface {
    position: absolute; left: 50%; top: 50%;
    width: calc(100% / .62); height: calc(100% / .62);
    transform: translate(-50%, -50%);
    pointer-events: none;
}
.rfx[data-celestial-ready], .rfx[data-mythical-ready], .rfx[data-gilded-ready],
.rfx[data-abyssal-ready], .rfx[data-overgrown-ready], .rfx[data-ink-ready], .rfx[data-unique-ready],
.rfx[data-stormforged-ready], .rfx[data-blueprint-ready], .rfx[data-deepfried-ready], .rfx[data-glitch-ready] { overflow: visible; }
/* The circulating rim is Unique's look where its shader cannot run. */
.rfx[data-unique-ready] > .rfx-layer { display: none; }
