/* Shared decorative planes: the real text remains on its own selectable layer. */
.intro-portrait .ability-parallax,
.intro-portrait .ability-drift { position: relative; }
.intro-portrait .ability-parallax { isolation: isolate; }
.intro-portrait .ability-drift { z-index: 1; }
.ability-effect {
  position: absolute;
  opacity: 0;
  visibility: hidden;
  transition: opacity .32s ease, visibility .32s;
}
.ability-effect, .ability-effect * {
  pointer-events: none !important;
  -webkit-user-select: none !important;
  user-select: none !important;
}
.intro-person .intro-portrait .ability-effect-motion { animation-play-state: paused !important; }
html:not(.motion-paused):not(.text-selection-active):not(.tab-inactive) .intro-person.is-ambient .intro-portrait:is([data-portrait-open="true"],[data-portrait-present="true"]) .ability-effect {
  opacity: 1;
  visibility: visible;
}
html:not(.motion-paused):not(.text-selection-active):not(.tab-inactive) .intro-person.is-ambient .intro-portrait:is([data-portrait-open="true"],[data-portrait-present="true"]) .ability-effect-motion {
  animation-play-state: var(--life-state,paused) !important;
}
:is(.motion-paused,.text-selection-active,.tab-inactive) .ability-effect { visibility: hidden; opacity: 0; transition: none; }

/* FX: the origins are sampled from the actual F and X glyph strokes. */
.ability-fx-simulation {
  --grain-range: 1;
  inset: 0;
  clip-path: inset(-48px -32px -24px);
}
.ability-fx-grain {
  position: absolute;
  width: var(--grain-size);
  height: var(--grain-size);
  background: var(--skill-fx);
  box-shadow: 0 0 5px color-mix(in srgb,var(--skill-fx) 55%,transparent);
  border-radius: 1px;
  opacity: 0;
  animation: ability-grain-release var(--grain-duration) linear var(--grain-delay) infinite;
}
.ability-fx-grain:nth-child(3n) { border-radius: 50%; background: var(--ink); }
.ability-fx-grain:nth-child(5n) { height: 2px; }
@keyframes ability-grain-release {
  0%,8% { opacity: 0; transform: translate3d(0,0,0) scale(.25); }
  17% { opacity: .95; transform: translate3d(calc(var(--grain-dx) * .06),calc(var(--grain-dy) * .06),0) scale(.9); }
  52% { opacity: .75; transform: translate3d(calc(var(--grain-dx) * var(--grain-range) * .5),calc(var(--grain-dy) * var(--grain-range) * .68),0) rotate(calc(var(--grain-turn) * .5)) scale(.7); }
  92%,100% { opacity: 0; transform: translate3d(calc(var(--grain-dx) * var(--grain-range)),calc(var(--grain-dy) * var(--grain-range)),0) rotate(var(--grain-turn)) scale(.12); }
}

/* VFX: pulses travel through a small orbital field behind the word. */
.ability-vfx-field {
  z-index: 0;
  inset: -38% -38%;
  transform: translate3d(calc(var(--depth-x,0px) * -.15),calc(var(--depth-y,0px) * -.12),0);
  contain: paint;
}
.ability-vfx-orbits { display: block; width: 100%; height: 100%; overflow: visible; animation: ability-field-breathe 7s ease-in-out infinite alternate; }
.ability-vfx-orbits path { vector-effect: non-scaling-stroke; }
.ability-vfx-guide { stroke: var(--skill-vfx); stroke-width: .65; opacity: .23; }
.ability-vfx-current { stroke: var(--skill-vfx); stroke-width: 1.8; stroke-linecap: round; stroke-dasharray: 17 83; animation: ability-energy-flow 3.8s linear infinite; }
.ability-vfx-current-thin { stroke: var(--skill-code); stroke-width: 1; stroke-dasharray: 5 18 10 67; animation-duration: 4.7s; animation-direction: reverse; }
.ability-vfx-current-bright { stroke: var(--skill-code); stroke-width: 2.2; stroke-dasharray: 12 88; animation-duration: 3.1s; animation-delay: -1.5s; filter: drop-shadow(0 0 3px var(--skill-vfx)); }
.ability-vfx-back { transform-origin: 120px 75px; animation: ability-field-back 8s ease-in-out infinite alternate; }
.ability-vfx-front { transform-origin: 120px 75px; animation: ability-field-front 9s ease-in-out -3s infinite alternate; }
.ability-vfx-core { stroke: var(--skill-vfx); stroke-width: .8; stroke-dasharray: 8 92; opacity: .5; animation: ability-energy-flow 2.6s linear infinite reverse; }
@keyframes ability-energy-flow { to { stroke-dashoffset: -100; } }
@keyframes ability-field-breathe { from { opacity: .75; transform: scale(.95); } to { opacity: 1; transform: scale(1.02); } }
@keyframes ability-field-back { from { transform: rotate(-9deg) scaleY(.85); } to { transform: rotate(7deg) scaleY(1.06); } }
@keyframes ability-field-front { from { transform: rotate(8deg) scaleX(.96); } to { transform: rotate(-7deg) scaleX(1.03); } }
@media (max-width: 760px) {
  .ability-fx-simulation { --grain-range: .72; }
  .ability-vfx-field { inset: -30% -30%; }
}
@media print { .ability-effect { display: none !important; } }
