/* quote-elves.css: tiny machine elves that peek around quotation words.
 * Companion to js/quote-elves.js. Elves take their tint from the section's --glow.
 * Everything here is decorative: no pointer events, hidden from assistive tech,
 * and removed entirely for reduced motion, print and forced colours.
 */

.qe-host { position: relative; isolation: isolate; }

/* Painted behind the words (z-index -1 inside the section's own stacking
 * context), so text always stays on top. */
.qe-layer {
  position: absolute;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
  contain: layout style;
}
.qe-layer.qe-front { z-index: 2; }

.qe-elf {
  --qe-glow: var(--glow, #cfe6ea);
  --qe-skin: color-mix(in srgb, var(--qe-glow) 12%, #fffaf0);
  --qe-tint: color-mix(in srgb, var(--qe-glow) 78%, #ffffff);
  --qe-facet: color-mix(in srgb, var(--qe-glow) 72%, #3a3452);
  --qe-deep: color-mix(in srgb, var(--qe-glow) 22%, #08070d);
  position: absolute;
  opacity: 0;
  pointer-events: none;
  user-select: none;
}
/* Each elf is clipped along the word edge it emerges from, so it reads as
 * stepping out from behind the letters. */
.qe-side-top,
.qe-side-bottom { clip-path: inset(-400px -400px 0 -400px); }
.qe-side-bottom { transform: rotate(180deg); }          /* hangs upside down below the line */
.qe-side-left { clip-path: inset(-400px 0 -400px -400px); }
.qe-side-right { clip-path: inset(-400px -400px -400px 0); }
.qe-side-hang { clip-path: inset(0 -400px -400px -400px); }   /* drops from behind the citation number */

.qe-body,
.qe-act { position: absolute; inset: 0; }
.qe-body { transform: translateY(106%); }               /* hidden until animated */
.qe-side-left .qe-body { transform: translateX(106%); }
.qe-side-right .qe-body { transform: translateX(-106%); }
.qe-side-hang .qe-body { transform: translateY(-106%); }

.qe-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  filter:
    drop-shadow(0 0 1.5px color-mix(in srgb, var(--qe-glow) 60%, #ffffff))
    drop-shadow(0 0 5px color-mix(in srgb, var(--qe-glow) 60%, transparent));
}
.qe-svg.qe-flip { transform: scaleX(-1); }

.qe-halo {
  position: absolute;
  left: -28%;
  top: -20%;
  width: 156%;
  height: 140%;
  border-radius: 50%;
  background: radial-gradient(closest-side, color-mix(in srgb, var(--qe-glow) 40%, transparent), transparent);
  opacity: .4;
  animation: qe-pulse 1.4s ease-in-out infinite alternate;
}

/* Parts ----------------------------------------------------------------- */
.qe-skin { fill: var(--qe-skin); }
.qe-gem { fill: var(--qe-tint); opacity: .6; animation: qe-shimmer 1.6s ease-in-out infinite alternate; }
.qe-seam { fill: none; stroke: var(--qe-facet); stroke-width: .7; stroke-linecap: round; stroke-linejoin: round; opacity: .85; }
.qe-sheen { fill: none; stroke: #ffffff; stroke-width: .9; stroke-linecap: round; opacity: .8; }
.qe-hat { fill: var(--qe-tint); stroke: var(--qe-skin); stroke-width: .5; stroke-linejoin: round; }
.qe-line { fill: none; stroke: var(--qe-skin); stroke-width: 1.1; stroke-linecap: round; stroke-linejoin: round; }
.qe-thin { stroke-width: .7; }
.qe-bead { fill: #ffffff; animation: qe-twinkle .9s ease-in-out infinite alternate; }
.qe-eye,
.qe-mouth { fill: var(--qe-deep); }
.qe-glint { fill: #ffffff; }
.qe-wing { fill: var(--qe-tint); fill-opacity: .3; stroke: var(--qe-skin); stroke-width: .45; stroke-opacity: .8; }
/* Egg */
.qe-inner { fill: var(--qe-deep); }
.qe-eye-lit { fill: var(--qe-tint); }
.qe-jewel { fill: var(--qe-tint); stroke: var(--qe-facet); stroke-width: .35; animation: qe-shimmer 1.2s ease-in-out infinite alternate; }
.qe-shell { transform-box: view-box; }
/* Eye-orb */
.qe-ring { fill: none; stroke: var(--qe-tint); stroke-width: .7; opacity: .85; }
.qe-iris { fill: var(--qe-tint); }
.qe-iris-ring { fill: none; stroke: var(--qe-facet); stroke-width: .45; stroke-dasharray: .9 .7; }
.qe-look { transform-box: view-box; animation: qe-look 2.2s ease-in-out infinite; }
.qe-blink-group { transform-box: fill-box; transform-origin: center; animation: qe-blink 3.1s ease-in-out var(--qe-blink, 0s) infinite; }
.qe-lashes { transform-box: view-box; animation: qe-lash-blink 3.1s ease-in-out var(--qe-blink, 0s) infinite; }

/* Idle life: blinking, self-turning facets, wings, chatter. */
.qe-eyes { transform-box: fill-box; transform-origin: center; animation: qe-blink 3.1s ease-in-out var(--qe-blink, 0s) infinite; }
.qe-turn { transform-box: fill-box; transform-origin: center; animation: qe-turn 6s linear infinite; }
.qe-wings { transform-box: view-box; animation: qe-flutter .14s ease-in-out infinite alternate; }
.qe-mouth { transform-box: fill-box; transform-origin: center; animation: qe-chatter .5s ease-in-out infinite alternate; }
.qe-arm { transform-box: view-box; }

.is-waving .qe-arm { animation: qe-wave-raise .22s ease-out forwards, qe-wave .3s ease-in-out .22s infinite alternate; }
.is-singing .qe-mouth { animation-duration: .12s; }
.is-singing .qe-gem { animation-duration: .4s; }
.is-hatching .qe-shell { animation: qe-hatch var(--qe-act, 860ms) ease-in-out both; }
.is-winking .qe-blink-group { animation: qe-wink var(--qe-act, 800ms) ease-in-out both; }
.is-winking .qe-lashes { animation: qe-lash-wink var(--qe-act, 800ms) ease-in-out both; }
.is-winking .qe-look { animation-play-state: paused; }

/* Both arms up (hanging, holding on), one arm up (holding something). */
.qe-arm-l { transform-box: view-box; }
.qe-arms-up .qe-arm { animation: none; transform: rotate(-100deg); }
.qe-arms-up .qe-arm-l { transform: rotate(100deg); }
.qe-arm-up-r .qe-arm { animation: none; transform: rotate(-120deg); }
/* Perched on the letters: eyes drift down to look at them. */
.qe-perched .qe-eyes { translate: 0 .45px; transition: translate .4s ease; }

/* The extended family (js/elf-designs.js): idle life of their parts. */
.fe-tail { transform-box: view-box; animation: fe-tail 1.5s ease-in-out infinite alternate; }
.fe-bell { transform-box: view-box; transform-origin: 11px 14px; animation: fe-bell 1.1s ease-in-out infinite alternate; }
.fe-tendrils { transform-box: view-box; transform-origin: 11px 14px; animation: fe-curl 1.6s ease-in-out infinite alternate; }
.fe-lights .qe-bead { animation: fe-chase 1.2s linear infinite; }
.fe-lights .qe-bead:nth-child(2) { animation-delay: -.96s; }
.fe-lights .qe-bead:nth-child(3) { animation-delay: -.72s; }
.fe-lights .qe-bead:nth-child(4) { animation-delay: -.48s; }
.fe-lights .qe-bead:nth-child(5) { animation-delay: -.24s; }
.fe-flame { transform-box: view-box; animation: fe-flame .7s ease-in-out infinite alternate; }
.fe-stalks { transform-box: view-box; transform-origin: 25.6px 9px; animation: fe-stalks 2.2s ease-in-out infinite alternate; }
.fe-shards { transform-box: view-box; transform-origin: 10px 6px; animation: fe-float 1.8s ease-in-out infinite alternate; }
.fe-third { animation-delay: calc(var(--qe-blink, 0s) - 1.4s); }
.fe-tentacles { transform-box: view-box; transform-origin: 12px 17px; animation: fe-curl 1.3s ease-in-out infinite alternate; }
.fe-star-wobble { transform-box: view-box; transform-origin: 12px 10px; animation: fe-wobble 1.8s ease-in-out infinite alternate; }
.fe-slow-wings { animation-duration: .42s !important; }
.fe-eye-lit { fill: var(--qe-tint); filter: drop-shadow(0 0 1.5px var(--qe-glow)); }

/* A bubble blown by an elf, and the glints it pops into. */
.qe-bubble,
.qe-pop {
  position: absolute;
  display: block;
  opacity: 0;
  pointer-events: none;
  border-radius: 50%;
}
.qe-bubble {
  background:
    radial-gradient(circle at 32% 30%, rgba(255, 255, 255, .95) 0 12%, transparent 22%),
    radial-gradient(circle, transparent 52%, color-mix(in srgb, var(--qe-glow) 55%, transparent) 72%, color-mix(in srgb, var(--qe-glow) 90%, #fff) 100%);
  box-shadow: 0 0 5px color-mix(in srgb, var(--qe-glow) 50%, transparent);
}
.qe-pop { width: 2px; height: 2px; background: #fff; box-shadow: 0 0 3px 1px var(--qe-tint); }

.qe-spark {
  position: absolute;
  display: block;
  opacity: 0;
  pointer-events: none;
}
.qe-spark svg {
  display: block;
  width: 100%;
  height: 100%;
  fill: #ffffff;
  filter: drop-shadow(0 0 2px var(--qe-tint)) drop-shadow(0 0 4px color-mix(in srgb, var(--qe-glow) 70%, transparent));
}

@keyframes qe-blink { 0%, 44%, 52%, 100% { transform: scaleY(1); } 48% { transform: scaleY(.1); } }
@keyframes qe-turn { to { transform: rotate(360deg); } }
@keyframes qe-shimmer { from { opacity: .3; } to { opacity: .85; } }
@keyframes qe-twinkle { from { opacity: .55; } to { opacity: 1; } }
@keyframes qe-flutter { from { transform: scaleX(1); } to { transform: scaleX(.4); } }
@keyframes qe-chatter { from { transform: scaleY(.35); } to { transform: scaleY(1.2); } }
@keyframes qe-pulse { from { opacity: .22; transform: scale(.9); } to { opacity: .5; transform: scale(1.04); } }
@keyframes qe-wave-raise { to { transform: rotate(-125deg); } }
@keyframes qe-wave { from { transform: rotate(-100deg); } to { transform: rotate(-145deg); } }
/* Lid hinges open on the left (after a shiver), holds while the eyes peer out, snaps shut. */
@keyframes qe-hatch {
  0%, 16% { transform: translate(0, 0) rotate(0deg); animation-timing-function: cubic-bezier(.3, 1.5, .5, 1); }
  34% { transform: translate(-.3px, -3.4px) rotate(-26deg); }
  72% { transform: translate(-.3px, -3px) rotate(-22deg); animation-timing-function: cubic-bezier(.6, 0, .9, .5); }
  86% { transform: translate(0, .3px) rotate(1deg); }
  100% { transform: translate(0, 0) rotate(0deg); }
}
@keyframes qe-look {
  0%, 18% { transform: translate(0, 0); }
  28%, 46% { transform: translate(-1.4px, .2px); }
  56%, 76% { transform: translate(1.4px, -.3px); }
  86%, 100% { transform: translate(0, 0); }
}
@keyframes qe-lash-blink { 0%, 44%, 52%, 100% { transform: translateY(0); } 48% { transform: translateY(5.6px); } }
@keyframes qe-wink { 0%, 100% { transform: scaleY(1); } 28%, 62% { transform: scaleY(.1); } }
@keyframes fe-tail { from { transform: rotate(-8deg); } to { transform: rotate(10deg); } }
@keyframes fe-bell { from { transform: scale(1.05, .94); } to { transform: scale(.96, 1.05); } }
@keyframes fe-chase { 0%, 100% { opacity: .35; } 20% { opacity: 1; } }
@keyframes fe-flame { from { transform: scale(.96, 1.04) skewX(-3deg); } to { transform: scale(1.04, .97) skewX(3deg); } }
@keyframes fe-stalks { from { transform: rotate(-6deg); } to { transform: rotate(5deg); } }
@keyframes fe-float { from { transform: translateY(.6px); } to { transform: translateY(-.8px); } }
@keyframes fe-curl { from { transform: skewX(-7deg); } to { transform: skewX(7deg); } }
@keyframes fe-wobble { from { transform: rotate(-9deg); } to { transform: rotate(9deg); } }
@keyframes qe-lash-wink { 0%, 100% { transform: translateY(0); } 28%, 62% { transform: translateY(5.6px); } }

/* Phone: a softer glow to match the smaller figures. */
@media (max-width: 640px) {
  .qe-svg {
    filter:
      drop-shadow(0 0 1px color-mix(in srgb, var(--qe-glow) 60%, #ffffff))
      drop-shadow(0 0 3.5px color-mix(in srgb, var(--qe-glow) 55%, transparent));
  }
  .qe-halo { opacity: .3; }
}

@media (prefers-reduced-motion: reduce) {
  .qe-layer { display: none !important; }
}
@media print, (forced-colors: active) {
  .qe-layer { display: none !important; }
}
