:root { --night: #21134f; --violet: #6133a5; --purple: #8d59c9; --gold: #ffd84d; --orange: #f2753b; --mint: #73e1c3; --cream: #fff2c9; --ink: #321660; --mono: 'DM Mono', monospace; --round: 'Nunito', sans-serif; }
* { box-sizing: border-box; } html { scroll-behavior: smooth; } body { margin: 0; overflow-x: hidden; background: var(--night); color: var(--cream); font-family: var(--round); } a { color: inherit; text-decoration: none; } button { font: inherit; cursor: pointer; } .sky-grain { position: fixed; inset: 0; z-index: 20; pointer-events: none; opacity: .035; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence baseFrequency='.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); }
.topbar { position: absolute; inset: 0 0 auto; z-index: 10; height: 82px; display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; padding: 0 clamp(1.25rem, 5vw, 5rem); border-bottom: 1px solid rgba(255,242,201,.25); background: rgba(26,14,66,.2); }.brand { justify-self: start; font-size: 1.15rem; font-weight: 900; letter-spacing: -.08em; }.brand span { color: var(--gold); }.brand small { color: rgba(255,242,201,.7); font-size: .55em; letter-spacing: 0; }.desktop-nav { display: flex; gap: 2.5rem; justify-self: center; color: rgba(255,242,201,.72); font-size: .78rem; font-weight: 800; }.desktop-nav a { position: relative; transition: color .2s; }.desktop-nav a:hover, .desktop-nav .active { color: var(--gold); }.desktop-nav .active:after { content: ''; position: absolute; left: 50%; bottom: -.8rem; width: 5px; height: 5px; transform: translateX(-50%); border-radius: 50%; background: var(--gold); }.message-button { justify-self: end; border: 1px solid rgba(255,216,77,.7); border-radius: 99px; padding: .65rem 1rem; color: var(--cream); background: rgba(33,19,79,.35); font-size: .7rem; font-weight: 800; }.message-button b { color: var(--gold); margin-left: .55rem; }.menu-toggle, .mobile-menu { display: none; }
.hero-world { position: relative; min-height: 100svh; overflow: hidden; isolation: isolate; background: linear-gradient(180deg, #4f96d2 0%, #7dc9dc 42%, #a17bd1 73%, #4f9e67 100%); }.hero-world:after { content: ''; position: absolute; inset: 0; z-index: -1; background: linear-gradient(180deg, rgba(33,19,79,.3), transparent 35%, rgba(33,19,79,.12)); }.hero-inner { position: relative; z-index: 1; display: grid; grid-template-columns: minmax(300px, .86fr) minmax(340px, .9fr); align-items: center; gap: clamp(2rem, 6vw, 8rem); max-width: 1180px; min-height: 100svh; margin: 0 auto; padding: 7rem 5vw 7rem; }.hero-copy { position: relative; z-index: 3; padding-top: 2rem; }.kicker { margin: 0 0 1.1rem; color: var(--gold); font: .68rem var(--mono); letter-spacing: .08em; text-transform: uppercase; font-weight: 500; }.hero-copy h1 { margin: 0; color: var(--cream); font-size: clamp(5.2rem, 9.8vw, 10.6rem); line-height: .77; letter-spacing: -.095em; font-weight: 900; text-shadow: .06em .07em 0 rgba(49,22,96,.35); }.hero-copy h1 span, .section-heading h2 span, .contact-strip h2 span { color: var(--gold); }.bio { max-width: 300px; margin: 2rem 0 1.8rem; color: rgba(255,242,201,.9); font-size: 1rem; line-height: 1.45; font-weight: 700; }.hero-actions { display: flex; align-items: center; gap: 1.2rem; }.portal-button { display: inline-flex; align-items: center; gap: 1rem; border: 3px solid #ffe785; border-radius: 8px; padding: .9rem 1.05rem; color: var(--ink); background: var(--orange); box-shadow: 0 5px 0 #6133a5; font-size: .73rem; font-weight: 900; transition: transform .2s, background .2s; }.portal-button:hover { transform: translateY(-3px); background: var(--gold); }.portal-button b { font-size: 1.15rem; }.text-button { padding: .4rem 0; border: 0; border-bottom: 1px solid rgba(255,242,201,.6); color: var(--cream); background: none; font: .65rem var(--mono); text-transform: uppercase; }
.character-portal { position: relative; justify-self: center; width: min(39vw, 490px); aspect-ratio: .78; display: grid; place-items: end center; border-radius: 47% 47% 14% 14%; background: linear-gradient(180deg, rgba(105,66,179,.8), rgba(34,18,82,.94)); border: 4px solid var(--gold); box-shadow: 0 0 0 9px rgba(255,216,77,.23), 0 0 90px rgba(255,241,157,.3), 16px 18px 0 rgba(33,19,79,.25); overflow: hidden; }.character-portal:before, .character-portal:after { content: ''; position: absolute; left: 8%; right: 8%; height: 8px; border-radius: 99px; background: rgba(255,216,77,.5); }.character-portal:before { top: 12%; }.character-portal:after { bottom: 12%; }.character-portal img { position: relative; z-index: 2; width: 100%; height: 100%; object-fit: cover; object-position: center top; filter: saturate(1.12); }.portal-ring { position: absolute; z-index: 1; width: 78%; aspect-ratio: 1; top: 16%; border: 1px solid rgba(255,238,135,.75); border-radius: 50%; box-shadow: 0 0 0 22px rgba(255,216,77,.07), 0 0 42px rgba(255,216,77,.25); }.portal-glow { position: absolute; z-index: 1; width: 70%; aspect-ratio: 1; top: 18%; border-radius: 50%; background: rgba(255,216,77,.18); filter: blur(30px); }.portal-rune { position: absolute; z-index: 4; top: 6%; right: 9%; color: var(--gold); font-size: 1.5rem; animation: twinkle 2.8s ease-in-out infinite; }.portal-label { position: absolute; z-index: 4; bottom: 4%; left: 8%; color: var(--cream); font: .62rem var(--mono); }.sun { position: absolute; z-index: -1; top: 16%; right: 13%; width: clamp(6rem, 12vw, 11rem); aspect-ratio: 1; border-radius: 50%; background: var(--gold); box-shadow: 0 0 0 2rem rgba(255,216,77,.15), 0 0 7rem rgba(255,216,77,.48); }.cloud { position: absolute; z-index: 0; width: 22rem; height: 5rem; border-radius: 99px; background: rgba(255,255,255,.35); filter: blur(1px); }.cloud:before, .cloud:after { content: ''; position: absolute; bottom: 0; border-radius: 50%; background: inherit; }.cloud:before { left: 15%; width: 8rem; height: 8rem; }.cloud:after { right: 12%; width: 6rem; height: 6rem; }.cloud-one { top: 25%; left: -5rem; }.cloud-two { top: 16%; right: -7rem; transform: scale(.72); opacity: .7; }.mountains { position: absolute; z-index: 0; left: -5%; width: 110%; clip-path: polygon(0 100%, 0 72%, 10% 62%, 18% 72%, 27% 42%, 36% 68%, 46% 50%, 55% 76%, 66% 38%, 76% 66%, 87% 47%, 100% 69%, 100% 100%); }.far-mountains { bottom: 18%; height: 38%; background: rgba(90,64,152,.54); }.near-mountains { bottom: 9%; height: 34%; background: rgba(62,83,139,.65); transform: scaleX(-1); }.grass-bank { position: absolute; z-index: 2; bottom: -10%; left: -5%; width: 110%; height: 24%; border-radius: 50% 50% 0 0; background: #4c9a61; box-shadow: inset 0 18px 0 rgba(119,223,126,.28); transform: rotate(-2deg); }.floating-island { position: absolute; z-index: 1; width: 9rem; height: 3rem; border-radius: 50%; background: #6bc57a; box-shadow: 0 1.5rem 0 -1rem #7749a2; }.island-left { bottom: 25%; left: 6%; transform: rotate(-9deg); }.island-right { top: 42%; right: 3%; transform: scale(.7) rotate(11deg); }.sparkles i { position: absolute; z-index: 2; width: 8px; height: 8px; border-radius: 50%; background: var(--gold); box-shadow: 0 0 12px var(--gold); animation: float 4s ease-in-out infinite; }.sparkles i:nth-child(1) { left: 20%; top: 30%; }.sparkles i:nth-child(2) { left: 43%; top: 16%; animation-delay: -.8s; }.sparkles i:nth-child(3) { right: 21%; top: 29%; animation-delay: -1.6s; }.sparkles i:nth-child(4) { right: 8%; bottom: 33%; animation-delay: -.3s; }.sparkles i:nth-child(5) { left: 47%; bottom: 24%; animation-delay: -2s; }.hero-tag, .scroll-hint { position: absolute; z-index: 4; bottom: 1.8rem; color: rgba(255,242,201,.75); font: .58rem var(--mono); letter-spacing: .1em; }.hero-tag { left: 5vw; }.hero-tag span { color: var(--gold); }.scroll-hint { right: 5vw; }.scroll-hint span { color: var(--gold); font-size: 1rem; margin-left: .5rem; }
.homeworlds { position: relative; padding: 7rem 5vw 8rem; background: #24124e; }.section-heading { max-width: 1160px; margin: 0 auto 2.5rem; }.section-heading h2, .contact-strip h2 { margin: 0; font-size: clamp(3.8rem, 8vw, 8rem); line-height: .8; letter-spacing: -.08em; }.portal-list { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; max-width: 1160px; margin: auto; }.realm-card { min-height: 180px; display: flex; flex-direction: column; justify-content: space-between; border: 2px solid rgba(255,242,201,.3); border-radius: 18px; padding: 1.4rem; overflow: hidden; transition: transform .25s, border-color .25s; }.realm-card:hover { transform: translateY(-8px) rotate(-1deg); border-color: var(--gold); }.realm-card.artisans { background: linear-gradient(145deg, #c27e44, #5c2d82); }.realm-card.magic { background: linear-gradient(145deg, #355caa, #7443ad); }.realm-card.dream { background: linear-gradient(145deg, #7d54ba, #ce6590); }.realm-gem { width: 32px; height: 42px; clip-path: polygon(50% 0, 100% 30%, 79% 100%, 21% 100%, 0 30%); background: var(--gold); box-shadow: inset 0 0 15px rgba(255,255,255,.7); }.realm-card strong { display: block; margin-top: 1.7rem; font-size: 1.3rem; }.realm-card small { display: block; margin-top: .2rem; color: rgba(255,242,201,.72); }.realm-card b { align-self: end; color: var(--gold); font-size: 1.4rem; }.contact-strip { padding: 8rem 5vw 10rem; text-align: center; background: linear-gradient(180deg, #24124e, #3c2079); }.contact-strip .kicker { margin-bottom: 1.4rem; }.contact-strip .portal-button { margin-top: 2.2rem; }
.toast { display: none; position: fixed; z-index: 30; left: 50%; bottom: 2rem; transform: translateX(-50%); padding: .8rem 1rem; border-radius: 8px; background: var(--gold); color: var(--ink); font: .7rem var(--mono); text-transform: uppercase; }.toast.visible { display: block; }
@keyframes float { 0%,100% { transform: translateY(0) scale(1); opacity: .65; } 50% { transform: translateY(-15px) scale(1.3); opacity: 1; } } @keyframes twinkle { 0%,100% { transform: rotate(0) scale(1); opacity: .65; } 50% { transform: rotate(20deg) scale(1.25); opacity: 1; } }
@media (max-width: 800px) { .topbar { height: 68px; grid-template-columns: 1fr auto; }.desktop-nav, .message-button { display: none; }.menu-toggle { display: block; justify-self: end; border: 1px solid var(--gold); border-radius: 99px; padding: .5rem .8rem; color: var(--cream); background: rgba(33,19,79,.5); font: .65rem var(--mono); text-transform: uppercase; }.mobile-menu { position: absolute; top: 68px; left: 1rem; right: 1rem; display: none; flex-direction: column; gap: 1rem; padding: 1.2rem; border: 2px solid var(--gold); border-radius: 14px; background: #2a155b; box-shadow: 0 10px 0 rgba(33,19,79,.3); }.mobile-menu.open { display: flex; }.mobile-menu a, .mobile-menu button { border: 0; padding: .5rem 0; color: var(--cream); background: none; text-align: left; font-weight: 800; }.hero-inner { grid-template-columns: 1fr; gap: 1.5rem; padding: 7rem 1.3rem 6rem; }.hero-copy { padding-top: 1rem; }.hero-copy h1 { font-size: clamp(4.6rem, 18vw, 7rem); }.bio { margin: 1.5rem 0; max-width: 260px; }.character-portal { width: min(78vw, 380px); justify-self: center; order: -1; }.hero-copy { order: 2; }.sun { top: 14%; right: 5%; }.far-mountains { bottom: 14%; }.near-mountains { bottom: 8%; }.floating-island { display: none; }.hero-tag { left: 1.3rem; bottom: .9rem; }.scroll-hint { right: 1.3rem; bottom: .9rem; }.portal-list { grid-template-columns: 1fr; max-width: 420px; }.realm-card { min-height: 130px; }.homeworlds { padding: 5rem 1.3rem; }.contact-strip { padding: 6rem 1.3rem 8rem; } }

@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } *, *:before, *:after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; } }
.topbar { position: sticky; top: 0; }
.mobile-menu { visibility: hidden; opacity: 0; pointer-events: none; transform: translateY(-12px); transition: opacity .2s ease, transform .2s ease, visibility .2s; }
.mobile-menu.open { visibility: visible; opacity: 1; pointer-events: auto; transform: translateY(0); }
@media (max-width: 800px) { .topbar { position: sticky; top: 0; }.mobile-menu { display: flex; } }
.mobile-menu.open { display: flex !important; visibility: visible !important; opacity: 1 !important; pointer-events: auto !important; transform: translateY(0) !important; }
.mobile-menu[hidden] { display: none !important; }
.topbar { z-index: 100; min-height: 82px; background: #261455; border-bottom: 1px solid rgba(255,242,201,.22); box-shadow: 0 4px 18px rgba(18,7,47,.28); }
.topbar:after { display: none; }
.site-footer { position: relative; z-index: 1; }
.site-footer { display: flex; align-items: center; justify-content: space-between; gap: 2rem; padding: 2rem 5vw; color: rgba(255,242,201,.72); background: #160b36; border-top: 1px solid rgba(255,216,77,.25); font-size: .72rem; }.site-footer strong { display: block; color: var(--cream); font-size: 1rem; letter-spacing: -.05em; }.site-footer strong span { color: var(--gold); }.site-footer small { display: block; margin-top: .35rem; color: rgba(255,242,201,.55); }.site-footer nav { display: flex; gap: 1.4rem; }.site-footer button { border: 0; padding: .2rem 0; color: inherit; background: none; font: .66rem var(--mono); cursor: pointer; }.site-footer button:hover { color: var(--gold); }
.legal-dialog { width: min(500px, calc(100% - 2rem)); border: 2px solid var(--gold); border-radius: 16px; padding: 2rem; color: var(--cream); background: #2a155b; box-shadow: 0 14px 0 rgba(10,4,30,.35); }.legal-dialog::backdrop { background: rgba(11,4,29,.7); backdrop-filter: blur(4px); }.legal-dialog h2 { margin: .2rem 0 1.2rem; font-size: 2.5rem; }.legal-dialog p { color: rgba(255,242,201,.82); line-height: 1.55; }.legal-dialog .kicker { color: var(--gold); }.legal-note { margin-top: 1.4rem; color: var(--mint) !important; font-size: .78rem; }.dialog-close { position: absolute; top: .8rem; right: 1rem; border: 0; color: var(--gold); background: none; font-size: 1.6rem; }
@media (max-width: 600px) { .site-footer { align-items: flex-start; flex-direction: column; gap: 1.1rem; padding: 1.5rem 1.3rem; }.site-footer nav { flex-wrap: wrap; gap: .8rem 1.2rem; } }

/* Spyro's hop loop is positioned by the single JavaScript animation controller. */
.runner-track {
  position: absolute;
  z-index: 3;
  left: 0;
  bottom: 0;
  width: clamp(78px, 7vw, 102px);
  height: clamp(86px, 8vw, 112px);
  pointer-events: none;
  transform: translate3d(0, 0, 0);
  will-change: transform;
}
.runner-sprite {
  position: absolute;
  inset: 0;
  filter: drop-shadow(0 6px 4px rgba(19, 10, 43, .22));
}
.sprite-frame {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  visibility: hidden;
  pointer-events: none;
  user-select: none;
}
.sprite-frame.is-active {
  visibility: visible;
}
.runner-sprite .sprite-frame {
  object-position: center bottom;
}
.runner-shadow {
  position: absolute;
  left: 25%;
  bottom: 4px;
  width: 50%;
  height: 8px;
  border-radius: 50%;
  background: rgba(21, 60, 38, .35);
  filter: blur(4px);
  transform-origin: center;
  will-change: transform, opacity;
}
@media (max-width: 800px) {
  .runner-track {
    width: 72px;
    height: 80px;
  }
}
@media (prefers-reduced-motion: reduce) {
  .runner-track { display: none; }
}

.scene-decor {
  position: absolute;
  z-index: 2;
  right: 20%;
  bottom: 14%;
  width: min(17vw, 190px);
  height: clamp(54px, 8vw, 98px);
  pointer-events: none;
}
.scene-prop {
  position: absolute;
  top: 0;
  left: 0;
  aspect-ratio: 1;
  pointer-events: none;
  isolation: isolate;
}
.scene-prop::before {
  content: '';
  position: absolute;
  z-index: 0;
  left: 50%;
  bottom: 0;
  height: 8px;
  border-radius: 50%;
  background: rgba(18, 48, 29, .28);
  filter: blur(4px);
  transform: translateX(-50%);
}
.scene-prop::after {
  content: '';
  position: absolute;
  z-index: 0;
  left: 50%;
  bottom: 0;
  height: 2px;
  border-radius: 50%;
  background: rgba(13, 34, 20, .28);
  filter: blur(1px);
  transform: translateX(-50%);
}
.scene-prop-image {
  position: relative;
  z-index: 1;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  filter: drop-shadow(0 5px 3px rgba(19, 10, 43, .2));
}
.scene-crystal {
  left: 0;
  height: 62%;
}
.scene-portal {
  right: 0;
  height: 78%;
}
.balloon-scene {
  position: absolute;
  z-index: 4;
  top: 14%;
  left: 88%;
  width: clamp(68px, 9vw, 128px);
  aspect-ratio: 1;
  filter: drop-shadow(0 7px 4px rgba(19, 10, 43, .18));
  animation: balloon-float 13s ease-in-out infinite;
  will-change: transform;
}
@keyframes balloon-float {
  0% { transform: translate3d(0, 0, 0) rotate(-2deg); }
  25% { transform: translate3d(-18vw, -14px, 0) rotate(2deg); }
  50% { transform: translate3d(-36vw, 4px, 0) rotate(-1deg); }
  75% { transform: translate3d(-54vw, -11px, 0) rotate(2deg); }
  100% { transform: translate3d(-72vw, 0, 0) rotate(-2deg); }
}
@media (max-width: 800px) {
  .scene-decor {
    right: 10%;
    bottom: 13%;
    width: 27vw;
    height: 72px;
  }
  .balloon-scene {
    top: 18%;
    left: 88%;
    width: 84px;
  }
}
@media (prefers-reduced-motion: reduce) {
  .balloon-scene { display: none; }
}

/* Final scene scale and grounding adjustments. */
.character-portal {
  width: min(32vw, 400px);
}
.scene-decor {
  bottom: 11%;
  width: min(15vw, 165px);
  height: clamp(48px, 7vw, 84px);
}
.scene-crystal {
  left: -24%;
  height: 58%;
}
.scene-portal {
  right: 2%;
  height: 72%;
  transform: translateY(5px);
}
@media (max-width: 800px) {
  .scene-decor {
    bottom: 10%;
    width: 27vw;
    height: 72px;
  }
}

/* Scene pass: full-width balloon crossing and separated grass props. */
.scene-decor {
  left: 12%;
  right: auto;
  bottom: 14%;
  width: min(42vw, 420px);
  height: clamp(70px, 10vw, 120px);
}
.scene-crystal {
  left: 0;
  height: 66%;
}
.scene-portal {
  right: 0;
  height: 82%;
  transform: translateY(3px);
}
.balloon-scene {
  --balloon-size: clamp(68px, 9vw, 128px);
  left: calc(100% + var(--balloon-size));
  width: var(--balloon-size);
  animation-name: balloon-crossing;
  animation-duration: 15s;
  animation-timing-function: ease-in-out;
}
@keyframes balloon-crossing {
  0% { transform: translate3d(0, 0, 0) rotate(-2deg); }
  20% { transform: translate3d(-20vw, -14px, 0) rotate(2deg); }
  45% { transform: translate3d(-45vw, 5px, 0) rotate(-1deg); }
  70% { transform: translate3d(-70vw, -12px, 0) rotate(2deg); }
  100% { transform: translate3d(calc(-100vw - var(--balloon-size) - var(--balloon-size)), 0, 0) rotate(-2deg); }
}
@media (max-width: 800px) {
  .scene-decor {
    left: 8%;
    bottom: 13%;
    width: 64vw;
    height: 92px;
  }
  .balloon-scene {
    --balloon-size: 84px;
    left: calc(100% + var(--balloon-size));
  }
}

/* Ground the two scene props on the bright grass ridge. */
.scene-decor {
  inset: 0;
  width: auto;
  height: auto;
}
.scene-crystal {
  width: clamp(88px, 7vw, 104px);
  height: auto;
  aspect-ratio: 1;
  transform: none;
}
.scene-crystal::before {
  width: 34%;
  opacity: .95;
}
.scene-crystal::after {
  width: 19%;
}
.scene-crystal-image {
  transform: scale(1.05) rotate(-6deg);
  transform-origin: center bottom;
}
.scene-portal {
  width: clamp(123px, 10vw, 148px);
  height: auto;
  aspect-ratio: 1;
  transform: none;
}
.scene-portal::before {
  width: 44%;
  height: 6px;
  background: rgba(18, 48, 29, .2);
  filter: blur(4.5px);
  opacity: .8;
}
.scene-portal::after {
  width: 76%;
  height: 4px;
  background:
    radial-gradient(ellipse at 18% 50%, rgba(13, 34, 20, .26) 0 22%, transparent 76%),
    radial-gradient(ellipse at 82% 50%, rgba(13, 34, 20, .26) 0 22%, transparent 76%);
  filter: blur(1.5px);
  opacity: .8;
}
.scene-portal-image {
  transform: scale(0.95) rotate(-2deg);
  transform-origin: center bottom;
}
@media (max-width: 800px) {
  .scene-decor {
    inset: 0;
  }
  .scene-crystal {
    width: 70px;
  }
  .scene-portal {
    width: 101px;
  }
}

.mini-portal {
  --portal-energy: rgba(78, 238, 255, .78);
  --portal-highlight: rgba(226, 255, 255, .82);
  position: relative;
  display: block;
  flex: 0 0 80px;
  width: 80px;
  height: 80px;
  margin-bottom: .35rem;
  isolation: isolate;
  filter: drop-shadow(0 5px 5px rgba(10, 13, 36, .28));
}
.mini-portal img {
  position: absolute;
  z-index: 1;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  transition: filter .35s ease;
}
/* Box matches the measured cyan doorway in portal.png (x 30–69%, y 29–91%). */
.portal-energy {
  position: absolute;
  z-index: 2;
  left: 31%;
  top: 29%;
  width: 38%;
  height: 61%;
  overflow: hidden;
  border-radius: 50% 50% 10% 10% / 32% 32% 5% 5%;
  background: radial-gradient(ellipse at 50% 55%, var(--portal-highlight) 0 10%, var(--portal-energy) 45%, var(--portal-deep) 100%);
  box-shadow: inset 0 0 6px rgba(255, 255, 255, .35);
  opacity: .6;
  transition: opacity .45s ease, filter .45s ease;
}
.portal-energy::before,
.portal-energy::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 55%;
  width: 240%;
  aspect-ratio: 1;
  translate: -50% -50%;
  pointer-events: none;
}
.portal-energy::before {
  width: 190%;
  background: radial-gradient(circle, #fff 0 12%, var(--portal-highlight) 40%, var(--portal-energy) 75%);
  -webkit-mask: url("assets/images/portal-spiral.svg") center / contain no-repeat;
  mask: url("assets/images/portal-spiral.svg") center / contain no-repeat;
  filter: blur(.4px) drop-shadow(0 0 2px var(--portal-highlight));
  opacity: .5;
  animation: portal-energy-turn 4s linear infinite;
}
.portal-energy::after {
  background-image:
    radial-gradient(circle at 44% 40%, #fff 0 1.2px, transparent 2px),
    radial-gradient(circle at 58% 47%, var(--portal-highlight) 0 1.2px, transparent 2px),
    radial-gradient(circle at 47% 60%, #fff 0 1px, transparent 2px),
    radial-gradient(circle at 55% 63%, var(--portal-highlight) 0 1px, transparent 2px);
  opacity: 0;
  animation: portal-energy-turn 6s linear infinite reverse;
  transition: opacity .45s ease;
}
.realm-card.artisans .mini-portal {
  --portal-energy: rgba(67, 239, 255, .95);
  --portal-highlight: rgba(255, 228, 150, .95);
  --portal-deep: rgba(18, 112, 150, .95);
}
.realm-card.magic .mini-portal {
  --portal-energy: rgba(88, 150, 255, .95);
  --portal-highlight: rgba(210, 170, 255, .95);
  --portal-deep: rgba(52, 36, 150, .95);
}
.realm-card.dream .mini-portal {
  --portal-energy: rgba(80, 232, 255, .95);
  --portal-highlight: rgba(255, 165, 222, .95);
  --portal-deep: rgba(112, 48, 156, .95);
}
.mini-portal {
  transition: filter .45s ease;
}
.realm-card:hover .mini-portal,
.realm-card:focus-visible .mini-portal {
  filter: drop-shadow(0 5px 5px rgba(10, 13, 36, .28)) drop-shadow(0 0 9px var(--portal-energy));
}
.realm-card:hover .portal-energy,
.realm-card:focus-visible .portal-energy {
  opacity: 1;
  filter: brightness(1.18) saturate(1.15);
}
.realm-card:hover .portal-energy::before,
.realm-card:focus-visible .portal-energy::before {
  opacity: .9;
}
.realm-card:hover .portal-energy::after,
.realm-card:focus-visible .portal-energy::after {
  opacity: 1;
}
@keyframes portal-energy-turn {
  to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
  .portal-energy::before,
  .portal-energy::after { animation: none; }
  .portal-energy,
  .mini-portal img { transition: none; }
}

/* Hidden until script.js has loaded frames and applied positions. */
.runner-track,
.balloon-scene,
.scene-decor {
  visibility: hidden;
  opacity: 0;
  transition: opacity .15s ease;
}
.runner-track.is-ready,
.balloon-scene.is-ready,
.scene-decor.is-ready {
  visibility: visible;
  opacity: 1;
}
.balloon-scene:not(.is-ready) {
  animation-play-state: paused;
}
