@charset "UTF-8";
/* ==========================================================================
   Ashes of Al'ar — Tournament of Ages 2026
   "Sunwell Bazaar" design layer  ·  loaded ONLY by 2026a.html

   This file sits on top of site.main.css and never replaces it. It is written
   as a layer on the markup that is already there, so the page keeps working
   with JS off and nothing here leaks into index.html / 2025/index.html.

   Palette is the guild's existing Sin'dorei kit pushed for contrast:
   obsidian bases, Silvermoon crimson, Thalassian gold leaf, Sunwell bloom.

   Sections
     01  Tokens
     02  Typography
     03  Base, scrollbar, selection
     04  Ambient: embers, sunwell beam, veil
     05  Loader — "kindling the Sunwell"
     06  Hero
     07  Buttons — gilded WoW plates
     08  Section headings & dividers
     09  The booth: vendor board & grid
     10  Vendor panels — portal reveal
     11  Display treatment for wares
     12  Carousels
     13  Lightbox chrome
     14  Reveal on scroll / tilt / sheen
     15  Reduced motion, narrow screens, print
   ========================================================================== */


/* ==========================================================================
   01  Tokens
   ========================================================================== */

:root {
	/* Obsidian & shadow */
	--toa-void: #05030a;
	--toa-obsidian: #0b0710;
	--toa-stone: #150d14;
	--toa-ink: rgba(5, 3, 10, .82);

	/* Silvermoon crimson */
	--toa-blood-deep: #3a0a18;
	--toa-blood: #8e1230;
	--toa-crimson: #cb334b;
	/* matches $red */

	/* Thalassian gold leaf */
	--toa-gold-deep: #7a4a0e;
	--toa-gold-mid: #c08b1d;
	--toa-gold: #f9c53f;
	/* matches $orange */
	--toa-gold-lite: #ffe9a8;
	--toa-sunwell: #fff6d8;

	/* Arcane accents, used sparingly */
	--toa-arcane: #c56bff;
	--toa-mana: #57e0d8;

	/* Gold leaf with a bevel, for rules and frames */
	--toa-gild: linear-gradient(160deg,
			var(--toa-gold-deep) 0%,
			var(--toa-gold) 30%,
			var(--toa-sunwell) 46%,
			var(--toa-gold) 60%,
			var(--toa-gold-deep) 100%);

	--toa-gild-h: linear-gradient(90deg,
			transparent 0%,
			var(--toa-gold-deep) 12%,
			var(--toa-gold) 34%,
			var(--toa-sunwell) 50%,
			var(--toa-gold) 66%,
			var(--toa-gold-deep) 88%,
			transparent 100%);

	/* Bloom shadows */
	--toa-bloom-gold: 0 0 18px rgba(249, 197, 63, .45), 0 0 48px rgba(249, 197, 63, .18);
	--toa-bloom-blood: 0 0 22px rgba(203, 51, 75, .45), 0 0 60px rgba(142, 18, 48, .3);

	/* Motion */
	--toa-ease-out: cubic-bezier(.16, 1, .3, 1);
	--toa-ease-in-out: cubic-bezier(.65, 0, .35, 1);

	/* Layer plan. Magnific owns 1042+, so ambient chrome sits just below it. */
	--toa-z-panel: 1000;
	--toa-z-chrome: 1039;
	--toa-z-embers: 1040;
	--toa-z-beam: 1041;

	/* Live values written by JS */
	--toa-scroll: 0;
	--toa-mx: 50%;
	--toa-my: 50%;
}


/* ==========================================================================
   02  Typography

   scrivano (.brioso) and krete stay — they are the guild's brand faces.
   Cinzel joins as the engraved-caps accent for eyebrows, plates and labels,
   which is where the "carved into Silvermoon marble" feel comes from.
   ========================================================================== */

.toa-caps {
	font-family: "Cinzel", "scrivano", serif;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: .22em;
	line-height: 1.35;
}

.toa-eyebrow {
	display: block;
	font-family: "Cinzel", "scrivano", serif;
	font-weight: 600;
	font-size: clamp(.6rem, 1.6vw, .82rem);
	text-transform: uppercase;
	letter-spacing: .42em;
	text-align: center;
	/* letter-spacing adds its gap after the LAST character too, so the line box
	   is .42em wider than the glyphs and centring it leaves the text visibly
	   left of true centre. A negative right margin takes that phantom gap back
	   out. (An earlier text-indent here was the wrong tool — it only offsets the
	   first line, and did nothing at all while this was still left-aligned.) */
	margin: 0 -.42em 1.1em 0;
	color: var(--toa-gold);
	text-shadow: 0 0 14px rgba(249, 197, 63, .5);
	opacity: .92;
}

.toa-eyebrow--sm {
	font-size: clamp(.55rem, 1.4vw, .7rem);
	letter-spacing: .34em;
	margin-right: -.34em;
}

/* Gilded headings ------------------------------------------------------- */

/* Gold headings become struck gold leaf rather than flat orange. Applied with
   -webkit-text-fill-color so the underlying `.orange` colour is the fallback
   anywhere background-clip:text is unavailable.

   Every rule below carries its OWN clip declarations and none of them depend on
   an ancestor. An earlier draft scoped the base rule to `.vendor / #vendors /
   .hero` while leaving the .h1_larger gradient unscoped, so any gold heading
   outside those three containers got the gradient painted as a solid block
   behind its text. This stylesheet is loaded by 2026a.html alone, so the
   ancestor scoping bought nothing and cost correctness. */
@supports ((-webkit-background-clip: text) or (background-clip: text)) {

	.brioso.orange {
		/* The dark end stops at gold-mid, not gold-deep: these headings sit on
		   near-black boards, and a #7a4a0e floor dropped the descenders to
		   roughly the board's own value. */
		background-image: linear-gradient(178deg,
				var(--toa-sunwell) 0%,
				var(--toa-gold-lite) 16%,
				var(--toa-gold) 46%,
				#eab52f 74%,
				var(--toa-gold-mid) 100%);
		-webkit-background-clip: text;
		background-clip: text;
		-webkit-text-fill-color: transparent;
		/* text-shadow cannot show through clipped text; drop-shadow can. */
		filter: drop-shadow(0 1px 0 rgba(0, 0, 0, .85)) drop-shadow(0 0 22px rgba(249, 197, 63, .28));
	}

	.brioso.red {
		background-image: linear-gradient(178deg,
				#f2708a 0%,
				var(--toa-crimson) 45%,
				var(--toa-blood) 100%);
		-webkit-background-clip: text;
		background-clip: text;
		-webkit-text-fill-color: transparent;
		filter: drop-shadow(0 1px 0 rgba(0, 0, 0, .85)) drop-shadow(0 0 18px rgba(203, 51, 75, .3));
	}

	/* The largest titles get a slow specular sweep. Kept to .h1_larger only —
	   about a dozen elements — so this stays an event, not wallpaper. */
	.h1_larger.brioso.orange {
		background-image: linear-gradient(100deg,
				var(--toa-gold-mid) 0%,
				var(--toa-gold) 30%,
				var(--toa-sunwell) 44%,
				var(--toa-gold-lite) 50%,
				var(--toa-gold) 62%,
				var(--toa-gold-mid) 100%);
		background-size: 260% 100%;
		background-position: 130% 0;
		-webkit-background-clip: text;
		background-clip: text;
		-webkit-text-fill-color: transparent;
		animation: toa-sheen-text 9s var(--toa-ease-in-out) infinite;
	}
}

@keyframes toa-sheen-text {

	0%,
	72%,
	100% {
		background-position: 130% 0;
	}

	28%,
	44% {
		background-position: -30% 0;
	}
}

/* A gold rule with a centre gem under the major centred section titles. */
p.h1.brioso.text-center::after,
h2.h1.brioso.text-center::after {
	content: "";
	display: block;
	width: min(320px, 62%);
	height: 9px;
	margin: .7em auto .2em;
	background:
		/* centre gem */
		radial-gradient(closest-side, var(--toa-sunwell) 0 32%, var(--toa-gold) 34% 56%, rgba(249, 197, 63, 0) 60%) center/9px 9px no-repeat,
		/* hairline */
		var(--toa-gild-h) center/100% 1px no-repeat;
	filter: drop-shadow(0 0 6px rgba(249, 197, 63, .55));
	opacity: .95;
}

/* Body copy: a comfortable measure and warmer ink than pure white. */
.vendor .vender__content p:not([class*="h1"]):not([class*="h2"]):not([class*="h3"]):not([class*="h4"]),
#vendors .vender__content p:not([class*="h1"]):not([class*="h2"]):not([class*="h3"]):not([class*="h4"]) {
	color: rgba(255, 246, 216, .86);
	line-height: 1.62em;
}

.vendor .vender__content em,
#vendors .vender__content em {
	color: rgba(255, 233, 168, .92);
}

/* Lore blocks — the italic in-world passages — read as inscriptions. */
.vendor .vender__content p.orange > em,
#vendors .vender__content p.orange > em {
	display: block;
	padding: .2em 0 .2em 1.1em;
	border-left: 1px solid rgba(249, 197, 63, .45);
	box-shadow: -6px 0 18px -8px rgba(249, 197, 63, .5);
}

.vendor .vender__content a:not(.button-game),
#vendors .vender__content a:not(.button-game) {
	color: var(--toa-gold);
	text-decoration: none;
	background-image: linear-gradient(var(--toa-gold), var(--toa-gold));
	background-size: 0% 1px;
	background-position: 0 100%;
	background-repeat: no-repeat;
	transition: background-size .35s var(--toa-ease-out), color .25s, text-shadow .25s;
}

.vendor .vender__content a:not(.button-game):hover,
.vendor .vender__content a:not(.button-game):focus-visible,
#vendors .vender__content a:not(.button-game):hover,
#vendors .vender__content a:not(.button-game):focus-visible {
	color: var(--toa-sunwell);
	background-size: 100% 1px;
	text-shadow: 0 0 12px rgba(249, 197, 63, .8);
}


/* ==========================================================================
   03  Base, scrollbar, selection
   ========================================================================== */

html {
	background: var(--toa-void);
}

body {
	background: var(--toa-void);
	/* keeps overscroll and sub-pixel seams from flashing white */
}

::selection {
	background: rgba(203, 51, 75, .6);
	color: var(--toa-sunwell);
	text-shadow: none;
}

* {
	scrollbar-width: thin;
	scrollbar-color: var(--toa-blood) var(--toa-obsidian);
}

::-webkit-scrollbar {
	width: 11px;
	height: 11px;
}

::-webkit-scrollbar-track {
	background: var(--toa-obsidian);
}

::-webkit-scrollbar-thumb {
	background: linear-gradient(180deg, var(--toa-gold) 0%, var(--toa-blood) 55%, var(--toa-blood-deep) 100%);
	border: 2px solid var(--toa-obsidian);
}

::-webkit-scrollbar-thumb:hover {
	background: linear-gradient(180deg, var(--toa-sunwell) 0%, var(--toa-crimson) 55%, var(--toa-blood) 100%);
}

/* Visible focus everywhere. The base sheet has none, which made keyboard use
   guesswork on a page that is almost entirely links. */
a:focus-visible,
button:focus-visible,
[tabindex]:focus-visible {
	outline: 2px solid var(--toa-gold-lite);
	outline-offset: 3px;
	border-radius: 1px;
}

.vendor:focus,
.main:focus,
.vendor:focus-visible,
.main:focus-visible {
	outline: none;
	/* programmatic focus targets, not user-reachable */
}

/* Closed panels are inert; belt-and-braces so they can never be tabbed into. */
[inert] {
	pointer-events: none;
}


/* ==========================================================================
   04  Ambient: embers, sunwell beam, veil
   ========================================================================== */

/* Drifting phoenix embers, painted to one canvas by JS.

   width/height are explicit rather than `inset: 0`: <canvas> is a replaced
   element with an intrinsic size from its width/height attributes, so inset
   alone does NOT stretch it — it laid out at the full backing-store size
   (2560x1440 on a 2x display) and the blended layer swallowed the page. */
.toa-embers {
	position: fixed;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	z-index: var(--toa-z-embers);
	pointer-events: none;
	mix-blend-mode: screen;
	opacity: 0;
	transition: opacity 1.6s ease .5s;
}

.toa-lit .toa-embers {
	opacity: .9;
}

/* Sunwell beam — a scroll progress bar that tracks whichever surface is
   actually scrolling: the booth, or the open vendor panel. */
.toa-beam {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	height: 3px;
	z-index: var(--toa-z-beam);
	pointer-events: none;
	background: rgba(5, 3, 10, .55);
	opacity: 0;
	transition: opacity .5s ease;
	/* the spark's glow is centred on the beam head and hangs 13px past each
	   end; clip it so it can never contribute page overflow */
	overflow: hidden;
}

.toa-lit .toa-beam {
	opacity: 1;
}

.toa-beam__fill {
	height: 100%;
	width: 100%;
	transform-origin: 0 50%;
	transform: scaleX(var(--toa-scroll));
	background: linear-gradient(90deg,
			var(--toa-blood) 0%,
			var(--toa-crimson) 22%,
			var(--toa-gold) 62%,
			var(--toa-sunwell) 100%);
	box-shadow: 0 0 10px rgba(249, 197, 63, .85), 0 0 26px rgba(203, 51, 75, .55);
	will-change: transform;
}

/* The bright head of the beam. */
.toa-beam__spark {
	position: absolute;
	top: 50%;
	left: 0;
	width: 26px;
	height: 26px;
	margin: -13px 0 0 -13px;
	border-radius: 50%;
	background: radial-gradient(circle, rgba(255, 246, 216, .95) 0%, rgba(249, 197, 63, .5) 38%, rgba(249, 197, 63, 0) 70%);
	transform: translateX(calc(var(--toa-scroll) * 100vw));
	opacity: calc(.2 + var(--toa-scroll));
	will-change: transform;
}

/* Veil behind an open panel, so the booth reads as "back there" without
   transforming or blurring the whole 3000-line document. */
.toa-veil {
	position: fixed;
	inset: 0;
	z-index: 999;
	pointer-events: none;
	opacity: 0;
	visibility: hidden;
	background:
		radial-gradient(120% 90% at 50% 0%, rgba(142, 18, 48, .3) 0%, rgba(5, 3, 10, .92) 62%, var(--toa-void) 100%);
	transition: opacity .5s ease, visibility .5s;
}

body.vendoropen .toa-veil {
	opacity: 1;
	visibility: visible;
}


/* ==========================================================================
   05  Loader — "kindling the Sunwell"

   The triangle-mosaic phoenix stays (it is credited artwork). What changes is
   the frame around it: a real progress ring driven by image loading, rotating
   arcane sigils, and an exit that reads as ignition instead of a fade.
   ========================================================================== */

#loader {
	background:
		radial-gradient(circle at 50% 46%, rgba(142, 18, 48, .5) 0%, rgba(11, 7, 16, .96) 55%, var(--toa-void) 100%),
		#602863;
	/* the original purple stays as the deepest fallback */
	position: fixed;
	inset: 0;
	z-index: 2000;
	display: flex;
	align-items: center;
	justify-content: center;
	overflow: hidden;
}

/* Slow radial glow behind the mosaic. */
#loader::before {
	content: "";
	position: absolute;
	left: 50%;
	top: 46%;
	width: 78vmin;
	height: 78vmin;
	margin: -39vmin 0 0 -39vmin;
	border-radius: 50%;
	background: radial-gradient(circle, rgba(255, 246, 216, .22) 0%, rgba(249, 197, 63, .1) 38%, transparent 68%);
	animation: toa-breathe 4.5s var(--toa-ease-in-out) infinite;
	pointer-events: none;
}

@keyframes toa-breathe {

	0%,
	100% {
		transform: scale(.9);
		opacity: .55;
	}

	50% {
		transform: scale(1.08);
		opacity: 1;
	}
}

#loader .titler {
	position: absolute;
	left: 0;
	right: 0;
	top: 50%;
	transform: translateY(-50%);
	text-align: center;
	z-index: 3;
	pointer-events: none;
}

#loader .titler p.h1 {
	font-family: "Cinzel Decorative", "Cinzel", "scrivano", serif;
	font-weight: 700;
	letter-spacing: .14em;
	color: var(--toa-sunwell);
	text-shadow: 0 0 24px rgba(249, 197, 63, .75), 0 0 60px rgba(203, 51, 75, .5);
	opacity: 1 !important;
	/* the markup carries .opacity-80; full strength reads better here */
}

/* Progress readout replaces the static "LOADING". */
#loader .toa-load-status {
	font-family: "Cinzel", serif;
	font-size: clamp(.62rem, 1.8vw, .78rem);
	text-transform: uppercase;
	letter-spacing: .38em;
	text-indent: .38em;
	color: rgba(255, 246, 216, .82);
	margin: .9em 0 0;
	min-height: 1.4em;
}

#loader .toa-load-status b {
	font-weight: 600;
	color: var(--toa-gold);
}

/* Progress ring, stroke driven by --toa-progress (0 → 1). */
.toa-ring {
	position: absolute;
	left: 50%;
	top: 46%;
	width: 62vmin;
	height: 62vmin;
	margin: -31vmin 0 0 -31vmin;
	z-index: 2;
	pointer-events: none;
	overflow: visible;
}

/* cx/cy/r are attributes in the markup so this works without CSS geometry
   property support; only the rotation is done here. */
.toa-ring circle {
	fill: none;
	transform: rotate(-90deg);
	transform-origin: 50% 50%;
}

.toa-ring__track {
	stroke: rgba(255, 246, 216, .12);
	stroke-width: 1.5;
}

.toa-ring__fill {
	stroke: var(--toa-gold);
	stroke-width: 2.5;
	stroke-linecap: round;
	/* pathLength is normalised to 1 in the markup, so the dash maths is exact */
	stroke-dasharray: 1;
	stroke-dashoffset: calc(1 - var(--toa-progress, 0));
	filter: drop-shadow(0 0 6px rgba(249, 197, 63, .9));
	transition: stroke-dashoffset .45s var(--toa-ease-out);
}

/* Two counter-rotating sigil rings for depth. */
.toa-sigil {
	position: absolute;
	left: 50%;
	top: 46%;
	border-radius: 50%;
	border: 1px solid rgba(249, 197, 63, .22);
	pointer-events: none;
	z-index: 1;
}

.toa-sigil--a {
	width: 70vmin;
	height: 70vmin;
	margin: -35vmin 0 0 -35vmin;
	border-style: dashed;
	animation: toa-spin 46s linear infinite;
}

.toa-sigil--b {
	width: 86vmin;
	height: 86vmin;
	margin: -43vmin 0 0 -43vmin;
	border-color: rgba(203, 51, 75, .22);
	animation: toa-spin 72s linear infinite reverse;
}

@keyframes toa-spin {
	to {
		transform: rotate(360deg);
	}
}

#loader .credits {
	z-index: 4;
	color: rgba(255, 246, 216, .5);
	letter-spacing: .02em;
}

#loader .credits a {
	color: var(--toa-gold);
}

/* Ignition exit: flare, then the whole splash lifts away. */
#loader.toa-ignite {
	animation: toa-ignite .95s var(--toa-ease-in-out) forwards;
}

#loader.toa-ignite::after {
	content: "";
	position: absolute;
	inset: 0;
	background: radial-gradient(circle at 50% 46%, var(--toa-sunwell) 0%, rgba(249, 197, 63, .75) 22%, rgba(203, 51, 75, .25) 46%, transparent 72%);
	animation: toa-flare .95s ease-out forwards;
	pointer-events: none;
}

@keyframes toa-ignite {
	0% {
		opacity: 1;
		transform: scale(1);
		filter: brightness(1);
	}

	38% {
		opacity: 1;
		transform: scale(1.02);
		filter: brightness(1.5);
	}

	100% {
		opacity: 0;
		transform: scale(1.16);
		filter: brightness(2.4);
	}
}

@keyframes toa-flare {
	0% {
		opacity: 0;
		transform: scale(.55);
	}

	32% {
		opacity: .95;
		transform: scale(1);
	}

	100% {
		opacity: 0;
		transform: scale(1.9);
	}
}


/* ==========================================================================
   06  Hero
   ========================================================================== */

.hero {
	box-shadow: 0 5px 30px 25px rgba(5, 3, 10, .96);
}

/* Crimson bloom LAYERED OVER a flat scrim, not blended into it. A single
   radial ramp let the bright Eversong plate show through behind the crest at
   short viewports; keeping the scrim uniform holds the copy legible while the
   bloom still tints the top. */
.hero .hero__content {
	position: relative;
	border-color: rgba(249, 197, 63, .55);
	background:
		radial-gradient(115% 80% at 50% 6%, rgba(142, 18, 48, .4) 0%, rgba(142, 18, 48, .1) 46%, rgba(142, 18, 48, 0) 70%),
		radial-gradient(120% 100% at 50% 100%, rgba(5, 3, 10, .45) 0%, rgba(5, 3, 10, 0) 60%),
		rgba(5, 3, 10, .84);
	box-shadow:
		inset 0 0 0 1px rgba(255, 246, 216, .1),
		inset 0 0 120px rgba(203, 51, 75, .16);
}

@media (min-width: 768px) {
	.hero .hero__content {
		background:
			radial-gradient(115% 80% at 50% 6%, rgba(142, 18, 48, .4) 0%, rgba(142, 18, 48, .1) 46%, rgba(142, 18, 48, 0) 70%),
			radial-gradient(120% 100% at 50% 100%, rgba(5, 3, 10, .45) 0%, rgba(5, 3, 10, 0) 60%),
			rgba(5, 3, 10, .76);
	}
}

/* Inner hairline frame, inset from the gold border — the "double rule" that
   makes Silvermoon signage feel engraved rather than boxed. */
.hero .hero__content::before {
	content: "";
	position: absolute;
	inset: 9px;
	border: 1px solid rgba(249, 197, 63, .2);
	pointer-events: none;
	z-index: 1;
}

@media (min-width: 768px) {
	.hero .hero__content::before {
		inset: 14px;
	}
}

/* The crest is deliberately left alone now.

   No transform: it used to drift with the pointer, removed on request.

   And no `filter` either — a drop-shadow bloom here was dead code. The base
   stylesheet runs `fireFlicker` on this element, which animates `filter` on an
   infinite loop, and an animated property overrides the static declaration for
   as long as it runs. So the bloom never rendered once. (Should it ever be
   wanted, it has to go on a wrapper, or into the fireFlicker keyframes
   themselves.) z-index keeps the crest above the bloom disc behind it. */
.hero .intro__logo {
	position: relative;
	z-index: 2;
}

/* Bloom disc behind the crest. Sits on the wrapper so it cannot inherit the
   crest's own flicker animation. */
.hero .hero__content > div {
	position: relative;
}

.hero .hero__content > div::before {
	content: "";
	position: absolute;
	left: 50%;
	top: 0;
	width: 92%;
	max-width: 780px;
	aspect-ratio: 1 / 1;
	transform: translate(-50%, -24%);
	background: radial-gradient(circle, rgba(249, 197, 63, .2) 0%, rgba(203, 51, 75, .1) 34%, transparent 66%);
	/* Its own keyframe, not the loader's toa-breathe: `transform` is one
	   property, so a keyframe declaring `transform: scale()` REPLACES the
	   centring translate above rather than composing with it. Sharing
	   toa-breathe left this disc un-centred and pushed the page 21px wide. */
	animation: toa-bloom 7s var(--toa-ease-in-out) infinite;
	pointer-events: none;
	z-index: 0;
}

@keyframes toa-bloom {

	0%,
	100% {
		transform: translate(-50%, -24%) scale(.9);
		opacity: .55;
	}

	50% {
		transform: translate(-50%, -24%) scale(1.08);
		opacity: 1;
	}
}

.hero .hero-copy {
	position: relative;
	z-index: 2;
}

.hero .hero-copy .toa-eyebrow {
	margin-bottom: 1.6em;
}

.hero .hero-copy h4,
.hero .hero-copy p.h4 {
	color: rgba(255, 246, 216, .9);
	text-shadow: 0 2px 14px rgba(0, 0, 0, .9);
	max-width: 62ch;
	margin-inline: auto;
}

/* Scroll cue, below the nav row. */
/* Sits in the ~40px of clear space below the nav row. Kept deliberately short
   so it never crowds the buttons at any viewport height. */
.toa-scrollcue {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 10px;
	z-index: 101;
	text-align: center;
	pointer-events: none;
	line-height: 1;
}

.toa-scrollcue span {
	display: block;
	font-family: "Cinzel", serif;
	font-size: .54rem;
	line-height: 1;
	text-transform: uppercase;
	letter-spacing: .4em;
	text-indent: .4em;
	color: rgba(255, 233, 168, .6);
}

.toa-scrollcue::after {
	content: "";
	display: block;
	width: 1px;
	height: 16px;
	margin: 5px auto 0;
	background: linear-gradient(180deg, var(--toa-gold), transparent);
	animation: toa-cue 2.4s var(--toa-ease-in-out) infinite;
	transform-origin: 50% 0;
}

@keyframes toa-cue {

	0%,
	100% {
		transform: scaleY(.4);
		opacity: .35;
	}

	50% {
		transform: scaleY(1);
		opacity: 1;
	}
}

@media (max-height: 700px) {
	.toa-scrollcue {
		display: none;
	}
}

/* Hero filigree gets a faint glow so the corners read as metal. */
.hero .filigree {
	filter: drop-shadow(0 0 10px rgba(249, 197, 63, .3));
	z-index: 2;
}


/* ==========================================================================
   07  Buttons — gilded WoW plates

   The sprite buttons are the most authentic thing on the page, so they are
   kept and given light: a specular sweep, a bloom on hover, a real pressed
   state, and an ember burst thrown by JS on click.
   ========================================================================== */

.intro_nav a,
.backbutton a,
.gembutton a {
	transition: transform .22s var(--toa-ease-out), filter .28s ease;
	will-change: transform, filter;
}

.intro_nav a .button-game-bg-mid,
.backbutton a .button-game-bg-mid,
.gembutton a .button-game-bg-mid {
	position: relative;
	overflow: hidden;
	text-shadow: 0 0 8px #000, 0 0 22px rgba(249, 197, 63, .35);
}

/* Specular sweep. */
.intro_nav a .button-game-bg-mid::after,
.backbutton a .button-game-bg-mid::after,
.gembutton a .button-game-bg-mid::after {
	content: "";
	position: absolute;
	top: 0;
	bottom: 0;
	left: -60%;
	width: 45%;
	background: linear-gradient(100deg, transparent 0%, rgba(255, 246, 216, .5) 50%, transparent 100%);
	transform: skewX(-18deg);
	opacity: 0;
	pointer-events: none;
}

.intro_nav a:hover .button-game-bg-mid::after,
.intro_nav a:focus-visible .button-game-bg-mid::after,
.backbutton a:hover .button-game-bg-mid::after,
.backbutton a:focus-visible .button-game-bg-mid::after,
.gembutton a:hover .button-game-bg-mid::after,
.gembutton a:focus-visible .button-game-bg-mid::after {
	animation: toa-sweep .72s var(--toa-ease-out) forwards;
}

@keyframes toa-sweep {
	0% {
		left: -60%;
		opacity: 0;
	}

	14% {
		opacity: 1;
	}

	100% {
		left: 118%;
		opacity: 0;
	}
}

.intro_nav a:hover,
.intro_nav a:focus-visible,
.backbutton a:hover,
.backbutton a:focus-visible,
.gembutton a:hover,
.gembutton a:focus-visible {
	filter: drop-shadow(0 0 12px rgba(249, 197, 63, .6)) brightness(1.08);
}

.intro_nav a:active,
.backbutton a:active,
.gembutton a:active {
	transform: translateY(2px) scale(.985);
	filter: drop-shadow(0 0 6px rgba(249, 197, 63, .4)) brightness(.95);
}

/* The hero's nav plates, 15% smaller.

   `zoom` rather than `transform: scale()` on purpose. These plates are built
   from a fixed-size sprite — a repeating middle plus two 51x54 end caps at
   hard-coded background offsets — so scaling has to take the sprite, the caps,
   the offsets and the 54px line-height with it. zoom does all of that AND
   shrinks the layout box, where transform would leave the old footprint behind.
   That footprint matters here: with five plates the row already occupied 1362 of
   1440px, so it was one long label away from wrapping.

   It composes with the base sheet's own breakpoint transforms (scale .95 at
   1200px, 1.1 at 1400px) rather than replacing them, so the responsive sizing
   still works — every step just lands 15% smaller. The back button and gem
   buttons share the sprite styling but are deliberately left alone. */
.intro_nav a.button-game {
	zoom: .85;
}

/* The primary call to action carries a slow idle pulse so the eye lands there
   first without needing a colour change. */
#gotovendors {
	animation: toa-pulse 3.6s var(--toa-ease-in-out) infinite;
}

#gotovendors:hover,
#gotovendors:focus-visible {
	animation: none;
}

@keyframes toa-pulse {

	0%,
	100% {
		filter: drop-shadow(0 0 0 rgba(249, 197, 63, 0));
	}

	50% {
		filter: drop-shadow(0 0 14px rgba(249, 197, 63, .5));
	}
}

/* Ember burst thrown on click. */
.toa-spark {
	position: fixed;
	z-index: var(--toa-z-beam);
	width: 5px;
	height: 5px;
	margin: -2.5px 0 0 -2.5px;
	border-radius: 50%;
	pointer-events: none;
	background: radial-gradient(circle, var(--toa-sunwell) 0%, var(--toa-gold) 45%, rgba(249, 197, 63, 0) 72%);
	will-change: transform, opacity;
}


/* ==========================================================================
   08  Section headings & dividers
   ========================================================================== */

/* The divider art was being stretched: `.divider img` sets height:100% plus a
   `widows:auto` typo where `width:auto` was meant. Corrected here for this
   page so the accord crest keeps its aspect ratio. */
.divider img {
	width: auto;
	max-width: 100%;
	filter: drop-shadow(0 0 14px rgba(249, 197, 63, .4));
}

/* A travelling glint used to live here and has been removed deliberately.
   Two things were wrong with it. Its gradient was angled at 100deg across a box
   30% wide by the divider's full height — roughly square — so the `transparent`
   end stops only ever reached two opposite CORNERS, leaving the vertical edges
   at around 40% alpha. The result read as a hard-edged grey rectangle sliding
   past, not a sweep. And a near-white highlight over the maroon board came out
   grey rather than gold. There are also dozens of dividers on a page, all
   pulsing on the same loop, which is a lot of motion for pure ornament.

   The crest's gold bloom above is what actually sells these as struck metal,
   and it no longer needs `overflow: hidden` on the parent — which was only
   here to clip the glint, and was cropping the bloom itself. */


/* ==========================================================================
   09  The booth: vendor board & grid
   ========================================================================== */

#vendors {
	background-color: var(--toa-void);
}

/* Obsidian-and-gold panel treatment, replacing flat rgba black.
   Selector mirrors the base sheet's own `.vendor .vender__content,
   .vendorboard .vender__content` so it wins on specificity rather than on
   !important — which matters because the mobile block below has to be able to
   switch backdrop-filter back off. */
.vendor .vender__content,
.vendorboard .vender__content {
	border: 1px solid rgba(249, 197, 63, .34);
	background:
		linear-gradient(178deg, rgba(58, 10, 24, .5) 0%, rgba(5, 3, 10, .9) 42%, rgba(5, 3, 10, .94) 100%);
	box-shadow:
		0 0 0 1px rgba(0, 0, 0, .8),
		inset 0 0 0 1px rgba(255, 246, 216, .06),
		inset 0 90px 140px -90px rgba(203, 51, 75, .3),
		0 40px 120px rgba(0, 0, 0, .8);
	backdrop-filter: blur(6px) saturate(1.35);
	-webkit-backdrop-filter: blur(6px) saturate(1.35);
}

/* #vendors keeps its wood texture, layered under the same gradient. */
#vendors .vendorboard .vender__content {
	background:
		linear-gradient(178deg, rgba(58, 10, 24, .42) 0%, rgba(5, 3, 10, .84) 44%, rgba(5, 3, 10, .9) 100%),
		url("../../assets/images/wood-002.png") center center;
}

/* Inner hairline frame on every panel. */
.vender__content::before {
	content: "";
	position: absolute;
	inset: 10px;
	border: 1px solid rgba(249, 197, 63, .16);
	pointer-events: none;
	z-index: 0;
}

@media (min-width: 768px) {
	.vender__content::before {
		inset: 16px;
	}
}

.vender__content .filigree {
	filter: drop-shadow(0 0 12px rgba(249, 197, 63, .28));
	z-index: 2;
}

/* Panel crests get a bloom rather than sitting flat on the frame. */
.logointro img {
	filter: drop-shadow(0 10px 34px rgba(0, 0, 0, .85)) drop-shadow(0 0 40px rgba(249, 197, 63, .22));
}

/* --- The vendor grid: the page's shop window ---------------------------- */

#vendors .vendorgrid {
	gap: 6px;
}

#vendors .vendorgrid a {
	position: relative;
	overflow: hidden;
	/* the base sheet rotates and scales on hover; this reads as a lit display
	   case instead, driven by pointer-tracked tilt from JS */
	transition: filter .45s ease, box-shadow .45s ease;
	transform-style: preserve-3d;
}

#vendors .vendorgrid a img {
	display: block;
	box-shadow: none;
	transition: transform .6s var(--toa-ease-out), filter .45s ease;
	transform: translateZ(0);
}

/* Frame drawn from the corners on hover. */
#vendors .vendorgrid a::before,
#vendors .vendorgrid a::after {
	content: "";
	position: absolute;
	pointer-events: none;
	z-index: 3;
	transition: transform .5s var(--toa-ease-out), opacity .35s ease;
	opacity: 0;
}

/* top + left rules */
#vendors .vendorgrid a::before {
	left: 20px;
	top: 20px;
	right: 20px;
	bottom: 20px;
	border-top: 1px solid var(--toa-gold);
	border-left: 1px solid var(--toa-gold);
	transform: translate(8px, 8px);
}

/* bottom + right rules */
#vendors .vendorgrid a::after {
	left: 20px;
	top: 20px;
	right: 20px;
	bottom: 20px;
	border-bottom: 1px solid var(--toa-gold);
	border-right: 1px solid var(--toa-gold);
	transform: translate(-8px, -8px);
}

#vendors .vendorgrid a:hover::before,
#vendors .vendorgrid a:hover::after,
#vendors .vendorgrid a:focus-visible::before,
#vendors .vendorgrid a:focus-visible::after {
	opacity: 1;
	transform: translate(0, 0);
}

/* Resting vignette that lifts on hover. A vignette ONLY — an earlier bottom
   scrim here dimmed the vendor's name, which is painted into the artwork, and
   competed with it. The art is never desaturated, only lit. */
.toa-shade {
	position: absolute;
	inset: 20px;
	z-index: 2;
	pointer-events: none;
	background: radial-gradient(115% 92% at 50% 45%, transparent 42%, rgba(5, 3, 10, .45) 100%);
	transition: opacity .45s ease;
}

#vendors .vendorgrid a:hover .toa-shade,
#vendors .vendorgrid a:focus-visible .toa-shade {
	opacity: 0;
}

/* Hover cue. Deliberately NOT a nameplate: every tile is finished artwork that
   already carries the vendor's name, so repeating it both duplicated the label
   and covered the lettering. A corner chip says "this is a door" and leaves
   the art alone. */
.toa-plate {
	position: absolute;
	top: 28px;
	right: 28px;
	z-index: 4;
	padding: .5em .8em .45em;
	font-family: "Cinzel", "scrivano", serif;
	font-weight: 600;
	font-size: clamp(.52rem, 1vw, .64rem);
	line-height: 1;
	text-transform: uppercase;
	letter-spacing: .24em;
	text-indent: .24em;
	color: var(--toa-sunwell);
	background: rgba(5, 3, 10, .84);
	border: 1px solid rgba(249, 197, 63, .55);
	box-shadow: 0 0 18px rgba(249, 197, 63, .28), 0 6px 18px rgba(0, 0, 0, .8);
	pointer-events: none;
	opacity: 0;
	transform: translateY(-8px);
	transition: transform .45s var(--toa-ease-out), opacity .35s ease;
}

#vendors .vendorgrid a:hover .toa-plate,
#vendors .vendorgrid a:focus-visible .toa-plate {
	opacity: 1;
	transform: none;
}

#vendors .vendorgrid a:hover,
#vendors .vendorgrid a:focus-visible {
	filter: none;
	z-index: 100;
}

#vendors .vendorgrid a:hover img,
#vendors .vendorgrid a:focus-visible img {
	transform: scale(1.06);
	filter: brightness(1.12) saturate(1.08);
}

/* Neutralise the base sheet's rotate/scale so tilt owns the transform. */
@media (min-width: 768px) {

	#vendors .vendorgrid a:nth-child(odd):hover,
	#vendors .vendorgrid a:nth-child(even):hover {
		transform: none;
		filter: none;
	}
}


/* ==========================================================================
   10  Vendor panels — portal reveal

   The base sheet keeps panels at opacity 0 / z-index -1000 and jQuery
   animates opacity. Here the reveal is CSS-driven and staged, so entering a
   vendor's stall feels like stepping through a door: the panel lights, the
   crest drops in, the board rises, the filigree corners strike, and a gold
   flare washes across once.

   visibility:hidden on closed panels also stops their ~26 links being
   tabbable, which opacity:0 never did.
   ========================================================================== */

.vendor {
	visibility: hidden;
	pointer-events: none;
	transition: opacity .5s ease, visibility .5s ease;
}

.vendor.is-open {
	opacity: 1;
	visibility: visible;
	pointer-events: auto;
	z-index: var(--toa-z-panel);
}

.vendor .logointro,
.vendor .vender__content {
	opacity: 0;
	transition:
		opacity .6s ease,
		transform .8s var(--toa-ease-out);
}

.vendor .logointro {
	transform: translateY(-30px);
}

.vendor .vender__content {
	transform: translateY(38px) scale(.988);
}

.vendor.is-open .logointro {
	opacity: 1;
	transform: none;
	transition-delay: .12s;
}

.vendor.is-open .vender__content {
	opacity: 1;
	transform: none;
	transition-delay: .2s;
}

/* Filigree corners strike in, staggered. */
.vendor .vender__content .filigree {
	opacity: 0;
	transform: scale(.55);
	transition: opacity .5s ease, transform .7s var(--toa-ease-out);
}

.vendor.is-open .vender__content .filigree {
	opacity: 1;
	transform: none;
}

.vendor.is-open .vender__content .filigree_tl {
	transition-delay: .34s;
}

.vendor.is-open .vender__content .filigree_tr {
	transition-delay: .42s;
}

.vendor.is-open .vender__content .filigree_br {
	transition-delay: .5s;
}

.vendor.is-open .vender__content .filigree_bl {
	transition-delay: .58s;
}

/* One-shot gold flare across the board as it lands. */
.vendor .vender__content::after {
	content: "";
	position: absolute;
	inset: 0;
	pointer-events: none;
	z-index: 5;
	opacity: 0;
	background: radial-gradient(120% 70% at 50% 28%,
			rgba(255, 246, 216, .55) 0%,
			rgba(249, 197, 63, .2) 32%,
			transparent 66%);
}

.vendor.is-open .vender__content::after {
	animation: toa-portal 1.15s ease-out .18s forwards;
}

@keyframes toa-portal {
	0% {
		opacity: 0;
		transform: scale(.85);
	}

	24% {
		opacity: 1;
		transform: scale(1);
	}

	100% {
		opacity: 0;
		transform: scale(1.35);
	}
}

/* Back button: readable over any artwork, and it drops in with the panel. */
.vendor .backbutton {
	padding-top: 4px;
	background: linear-gradient(180deg, rgba(5, 3, 10, .92) 0%, rgba(5, 3, 10, .6) 55%, transparent 100%);
	top: 0 !important;
	padding-bottom: 26px;
	opacity: 0;
	transform: translateY(-16px);
	transition: opacity .5s ease .3s, transform .6s var(--toa-ease-out) .3s;
}

.vendor .backbutton a {
	margin-top: 16px;
}

.vendor.is-open .backbutton {
	opacity: 1;
	transform: none;
}

/* Panels scroll their own content; give them momentum and no scroll chaining. */
.vendor {
	overscroll-behavior: contain;
	-webkit-overflow-scrolling: touch;

	/* A panel must never scroll sideways. The base sheet sets only overflow-y,
	   and per spec that makes overflow-x compute to `auto` — so any stray pixel
	   anywhere in a 5,000px-tall stall produces a horizontal scrollbar. Pinning
	   it to hidden is the guarantee; the flex fix on the carousels above removes
	   the likeliest source. Safe for the lightbox and the back button: magnific
	   appends to <body>, and .backbutton is position:fixed with no transformed
	   ancestor, so neither is clipped by this. */
	overflow-x: hidden;
}

/* --- Jump bar: skip straight to a range inside a long panel ---------------
   These are `data-jump` buttons rather than href="#id" anchors on purpose. A
   real hash link would land in the panel router's popstate handler and fight
   the deep-link logic, and it would scroll the WINDOW — but a panel is its own
   overflow container, so the window is not what needs scrolling. */
.toa-jump {
	margin: 1.5em auto 2.5em;
	max-width: 1000px;
	padding: 1.1em 1.2em 1.3em;
	border: 1px solid rgba(249, 197, 63, .28);
	background: linear-gradient(178deg, rgba(58, 10, 24, .45) 0%, rgba(5, 3, 10, .55) 100%);
	box-shadow: inset 0 0 40px rgba(0, 0, 0, .5);
}

.toa-jump__title {
	margin: 0 0 .9em;
	text-align: center;
	font-family: "Cinzel", "scrivano", serif;
	font-weight: 600;
	font-size: .62rem;
	line-height: 1;
	text-transform: uppercase;
	letter-spacing: .34em;
	text-indent: .34em;
	color: rgba(255, 233, 168, .7);
}

.toa-jump__links {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: .5em .35em;
}

.toa-jump__link {
	display: block;
	padding: .5em .85em .45em;
	font-family: "Cinzel", "scrivano", serif;
	font-weight: 600;
	font-size: clamp(.58rem, 1.1vw, .7rem);
	line-height: 1.2;
	text-transform: uppercase;
	letter-spacing: .12em;
	text-align: center;
	color: var(--toa-gold-lite);
	text-decoration: none;
	border: 1px solid rgba(249, 197, 63, .3);
	background: rgba(5, 3, 10, .5);
	cursor: pointer;
	transition:
		color .25s ease,
		border-color .3s ease,
		background-color .3s ease,
		box-shadow .3s ease,
		transform .25s var(--toa-ease-out);
}

/* The body-copy link underline sweep in section 02 would fight this chip, so
   the jump links opt out of it explicitly. */
.vendor .vender__content a.toa-jump__link,
.vendor .vender__content a.toa-jump__link:hover,
.vendor .vender__content a.toa-jump__link:focus-visible {
	background-image: none;
	text-shadow: none;
}

.toa-jump__link:hover,
.toa-jump__link:focus-visible {
	color: var(--toa-sunwell);
	border-color: var(--toa-gold);
	background: rgba(142, 18, 48, .45);
	box-shadow: 0 0 18px rgba(249, 197, 63, .3), inset 0 0 18px rgba(249, 197, 63, .1);
	transform: translateY(-2px);
}

.toa-jump__link:active {
	transform: translateY(0);
}

/* Briefly ring the heading a jump lands on, so it is obvious where you arrived
   in a panel five thousand pixels long. */
@keyframes toa-landed {

	0%,
	100% {
		text-shadow: none;
	}

	30% {
		text-shadow: 0 0 26px rgba(255, 246, 216, .9), 0 0 60px rgba(249, 197, 63, .6);
	}
}

.toa-landed {
	animation: toa-landed 1.4s var(--toa-ease-in-out) 1;
}

@media (max-width: 575.98px) {
	.toa-jump {
		padding: .9em .6em 1em;
	}

	.toa-jump__link {
		letter-spacing: .06em;
		padding: .45em .6em .4em;
	}
}

/* Keyboard hint, injected once per panel by JS. */
.toa-hint {
	position: fixed;
	right: 14px;
	bottom: 14px;
	z-index: var(--toa-z-chrome);
	font-family: "Cinzel", serif;
	font-size: .6rem;
	text-transform: uppercase;
	letter-spacing: .22em;
	color: rgba(255, 233, 168, .55);
	background: rgba(5, 3, 10, .8);
	border: 1px solid rgba(249, 197, 63, .28);
	padding: .5em .8em;
	pointer-events: none;
	opacity: 0;
	transform: translateY(8px);
	transition: opacity .4s ease, transform .5s var(--toa-ease-out);
}

body.vendoropen .toa-hint {
	opacity: 1;
	transform: none;
	transition-delay: .9s;
}

body.vendoropen .toa-hint.is-dismissed {
	opacity: 0;
	transition-delay: 0s;
}

@media (max-width: 767.98px) {
	.toa-hint {
		display: none;
	}
}


/* ==========================================================================
   11  Display treatment for wares

   Every product shot is a `.popup-img`. They are not wrapped — wrapping 200+
   images would rewrite the box tree and risk the grid — so the treatment is
   done with border, shadow and filter only, which need no extra element.
   ========================================================================== */

.popup-img {
	cursor: zoom-in;
	background: rgba(5, 3, 10, .35);
	box-shadow:
		0 0 0 1px rgba(249, 197, 63, .12),
		0 18px 40px -22px rgba(0, 0, 0, .9);
	transition:
		transform .4s var(--toa-ease-out),
		box-shadow .4s ease,
		filter .4s ease;
}

/* The base sheet scales to 1.1 on hover, which overflows padded columns.
   1.04 plus a gold rim and bloom reads richer and stays inside its box. */
.popup-img:hover,
.popup-img:focus-visible {
	transform: scale(1.04);
	filter: brightness(1.15) saturate(1.06);
	box-shadow:
		0 0 0 1px rgba(249, 197, 63, .7),
		0 0 26px rgba(249, 197, 63, .35),
		0 26px 60px -26px rgba(0, 0, 0, .95);
}

/* Artist credit squares: gilded plinths with pointer tilt. */
.image__square > div {
	position: absolute;
	border: 1px solid rgba(249, 197, 63, .22);
	background:
		radial-gradient(120% 100% at 50% 0%, rgba(142, 18, 48, .3) 0%, rgba(5, 3, 10, .7) 70%);
	box-shadow: inset 0 0 40px rgba(0, 0, 0, .7), 0 18px 40px -24px rgba(0, 0, 0, .9);
	transition: border-color .4s ease, box-shadow .4s ease;
}

.image__square > div img {
	padding: 8%;
}

.image__square:hover > div {
	border-color: rgba(249, 197, 63, .65);
	box-shadow:
		inset 0 0 40px rgba(0, 0, 0, .5),
		0 0 30px rgba(249, 197, 63, .25),
		0 24px 50px -24px rgba(0, 0, 0, .95);
}

/* The rare-shiny reveal reads as legendary loot: an orange rarity glow. */
#shiny .slide {
	position: relative;
	padding: 1.4em 1em;
	border: 1px solid rgba(249, 197, 63, .5);
	background: radial-gradient(120% 90% at 50% 0%, rgba(249, 197, 63, .14) 0%, rgba(5, 3, 10, .8) 62%);
	box-shadow: 0 0 34px rgba(249, 197, 63, .3), inset 0 0 60px rgba(249, 197, 63, .08);
	animation: toa-legendary 4.5s var(--toa-ease-in-out) infinite;
}

@keyframes toa-legendary {

	0%,
	100% {
		box-shadow: 0 0 26px rgba(249, 197, 63, .22), inset 0 0 50px rgba(249, 197, 63, .06);
	}

	50% {
		box-shadow: 0 0 46px rgba(249, 197, 63, .45), inset 0 0 70px rgba(249, 197, 63, .14);
	}
}


/* ==========================================================================
   12  Carousels

   Four slick sliders share one visual language here: a framed stage, gilded
   arrow plates, and a thumbnail rail whose active gem is unmistakable. The
   old rail relied on opacity alone, which was hard to read at a glance.
   ========================================================================== */

.phoenixslider,
.dragons,
.squishies,
.covenantcompamions,
.toa-slider {
	position: relative;
	padding: 6px;
	border: 1px solid rgba(249, 197, 63, .2);
	background: linear-gradient(178deg, rgba(58, 10, 24, .3) 0%, rgba(5, 3, 10, .55) 100%);
	box-shadow: inset 0 0 60px rgba(0, 0, 0, .6);
}

/* --- .toa-sliderset: the layout for carousels added by this page -----------
   The four original carousels each carry their own near-identical copy of this
   geometry in site.main.css, and their rail is a SIBLING of the stage. Here the
   set wraps stage AND rail in one element, which is what lets the arrow keys
   work from a focused thumbnail and lets the JS pair them up without knowing
   either one's name. */

.toa-slider {
	display: flex;
}

/* Arrows hold their width and never shrink; the stage absorbs the remainder. */
.toa-slider .back,
.toa-slider .next,
.phoenixslider .back,
.phoenixslider .next,
.dragons .back,
.dragons .next,
.squishies .back,
.squishies .next,
.covenantcompamions .back,
.covenantcompamions .next {
	flex: 0 0 auto;
}

.toa-slider .back,
.toa-slider .next {
	width: 20px;
}

@media (min-width: 768px) {

	.toa-slider .back,
	.toa-slider .next {
		width: 35px;
	}
}

.toa-slider .back img,
.toa-slider .next img {
	width: 100%;
	height: auto;
	display: block;
}

/* Let flex do the arithmetic ------------------------------------------------
   Every carousel on this page sized its stage as `calc(100% - 70px)` beside two
   35px arrows, so the three children summed to EXACTLY the content box — zero
   headroom. That is fine until one pixel appears from somewhere, and then the
   panel scrolls sideways. Adding `padding: 6px` and a 1px border to the slider
   frame (section 12) made it tighter still.

   `flex: 1 1 auto` + `min-width: 0` lets the stage simply absorb whatever the
   arrows leave, so padding, borders, a classic scrollbar, browser zoom and
   sub-pixel rounding can no longer tip it over. min-width:0 is the important
   half: a flex item defaults to min-width:auto, which refuses to shrink below
   its content — and slick's track is thousands of pixels wide. */
.toa-slider__container,
.phoenixslider__container,
.dragons__container,
.squishies__container,
.covenantcompamions__container {
	width: auto;
	flex: 1 1 auto;
	min-width: 0;
	padding: 10px;
}

@media (min-width: 768px) {

	.toa-slider__container,
	.phoenixslider__container,
	.dragons__container,
	.squishies__container,
	.covenantcompamions__container {
		padding: 15px;
	}
}

.toa-slider .slide {
	display: flex;
	width: 100%;
	flex-direction: column;
	align-items: center;
}

@media (min-width: 768px) {
	.toa-slider .slide {
		flex-direction: row;
	}
}

.toa-slider .slide > div {
	width: 100%;
	padding: .5em;
}

@media (min-width: 768px) {
	.toa-slider .slide > div {
		width: 50%;
		padding: 1em;
	}
}

/* height:auto matters: these images carry width/height attributes, and without
   it the height attribute becomes the used height and the art distorts. */
.toa-slider .slide > div img {
	width: 100%;
	height: auto;
	display: block;
}

/* Alternate which side the art sits on, as the original carousels do. */
@media (min-width: 768px) {
	.toa-slider .slide:nth-child(even) > div:nth-child(1) {
		order: 2;
	}

	.toa-slider .slide:nth-child(even) > div:nth-child(2) {
		order: 1;
	}
}

.toa-slider__rail {
	display: flex;
	justify-content: center;
	flex-wrap: wrap;
}

.toa-slider__rail a {
	display: block;
	padding: 15px;
	width: calc(100% / 4);
}

@media (min-width: 768px) {
	.toa-slider__rail a {
		width: calc(100% / 8);
	}
}

.toa-slider__rail a img {
	width: 100%;
	height: auto;
	display: block;
}

/* Arrow plates. */
.phoenixslider .back,
.phoenixslider .next,
.dragons .back,
.dragons .next,
.squishies .back,
.squishies .next,
.covenantcompamions .back,
.covenantcompamions .next,
.toa-slider .back,
.toa-slider .next {
	transition: transform .3s var(--toa-ease-out), filter .3s ease;
}

.phoenixslider .back a,
.phoenixslider .next a,
.dragons .back a,
.dragons .next a,
.squishies .back a,
.squishies .next a,
.covenantcompamions .back a,
.covenantcompamions .next a,
.toa-slider .back a,
.toa-slider .next a {
	display: block;
	filter: drop-shadow(0 0 8px rgba(249, 197, 63, .3));
	transition: filter .3s ease, transform .3s var(--toa-ease-out);
}

.phoenixslider .back a:hover,
.phoenixslider .next a:hover,
.dragons .back a:hover,
.dragons .next a:hover,
.squishies .back a:hover,
.squishies .next a:hover,
.covenantcompamions .back a:hover,
.covenantcompamions .next a:hover,
.phoenixslider .back a:focus-visible,
.phoenixslider .next a:focus-visible,
.dragons .back a:focus-visible,
.dragons .next a:focus-visible,
.squishies .back a:focus-visible,
.squishies .next a:focus-visible,
.covenantcompamions .back a:focus-visible,
.covenantcompamions .next a:focus-visible,
.toa-slider .back a:hover,
.toa-slider .next a:hover,
.toa-slider .back a:focus-visible,
.toa-slider .next a:focus-visible {
	filter: drop-shadow(0 0 16px rgba(249, 197, 63, .85)) brightness(1.2);
	transform: scale(1.12);
}

/* Slide copy column gets breathing room and a gold rule against the image. */
@media (min-width: 768px) {

	.phoenixslider .slide > div:last-child,
	.dragons .slide > div:last-child,
	.squishies .slide > div:last-child,
	.covenantcompamions .slide > div:last-child {
		position: relative;
	}
}

/* Thumbnail rail: gilded gems.

   The rails carry a top margin because their thumbs GROW on hover/active
   (scale 1.18/1.24) and the top row was climbing over the stage frame's gold
   border above. ~19px is the worst-case overflow of a scaled thumb, so the
   growth now happens into clear air instead of over the frame. */
.phoenixslidercontrols,
.dragons__controls,
.squishies__controls,
.covenantcompamions__controls,
.toa-slider__rail {
	margin-top: 26px;
}

.phoenixslidercontrols a,
.dragons__controls a,
.squishies__controls a,
.covenantcompamions__controls a,
.toa-slider__rail a {
	position: relative;
	opacity: .38;
	filter: grayscale(.35) brightness(.8);
	transform: scale(1);
	transition:
		opacity .4s var(--toa-ease-out),
		transform .4s var(--toa-ease-out),
		filter .4s ease;
	cursor: pointer;
}

.phoenixslidercontrols a::after,
.dragons__controls a::after,
.squishies__controls a::after,
.covenantcompamions__controls a::after,
.toa-slider__rail a::after {
	content: "";
	position: absolute;
	inset: 2px;
	border: 1px solid transparent;
	/* softly rounded like a socketed WoW item slot; the glow box-shadows
	   follow this radius too, so the bloom rounds with it */
	border-radius: 10px;
	pointer-events: none;
	transition: border-color .35s ease, box-shadow .35s ease;
}

.phoenixslidercontrols a:hover,
.dragons__controls a:hover,
.squishies__controls a:hover,
.covenantcompamions__controls a:hover,
.phoenixslidercontrols a:focus-visible,
.dragons__controls a:focus-visible,
.squishies__controls a:focus-visible,
.covenantcompamions__controls a:focus-visible,
.toa-slider__rail a:hover,
.toa-slider__rail a:focus-visible {
	opacity: .85;
	filter: none;
	transform: scale(1.18);
}

.phoenixslidercontrols a.active,
.dragons__controls a.active,
.squishies__controls a.active,
.covenantcompamions__controls a.active,
.toa-slider__rail a.active {
	opacity: 1;
	filter: none;
	transform: scale(1.24);
	z-index: 2;
}

.phoenixslidercontrols a.active::after,
.dragons__controls a.active::after,
.squishies__controls a.active::after,
.covenantcompamions__controls a.active::after,
.toa-slider__rail a.active::after {
	border-color: var(--toa-gold);
	box-shadow: 0 0 16px rgba(249, 197, 63, .6), inset 0 0 16px rgba(249, 197, 63, .25);
}

/* Range headlines inside the Eversong group (Lil’ Wyrmlings / Hawkstriders /
   Dragonhawks). They first carried Bootstrap’s mt-5 (3rem); the owner asked for
   double that. Bootstrap’s scale stops at 5, hence the custom class — no
   !important needed since mt-5 was removed from the markup along with it. */
.toa-range-gap {
	margin-top: 6rem;
}

/* The prose-link underline sweep (section 02) matches EVERY anchor inside a
   board that is not a .button-game — which caught the image-only anchors too:
   rail thumbnails, the slider arrows, the vendor grid tiles. On those it drew a
   stray 1px gold line across the image bottom on hover. Image anchors opt out;
   real text links (artist credits, Wowhead links) keep their underline. Same
   specificity as the section-02 rule, later in the file, so it wins. */
.vendor .vender__content .phoenixslidercontrols a,
.vendor .vender__content .dragons__controls a,
.vendor .vender__content .squishies__controls a,
.vendor .vender__content .covenantcompamions__controls a,
.vendor .vender__content .toa-slider__rail a,
.vendor .vender__content .back a,
.vendor .vender__content .next a,
#vendors .vender__content .vendorgrid a {
	background-image: none;
	text-shadow: none;
}

/* Slide counter, injected per slider by JS.
   Top margin is in rem, not em: the counter's own font is only ~11px, and an
   em-based gap left it inside the reach of the rail's active gem — thumbs scale
   to 1.24–1.3 past their box and carry a glow ring on top of that. 1.75rem
   clears the scaled edge with the soft shadow only feathering into the gap. */
.toa-count {
	display: block;
	margin: 1.75rem 0 0;
	text-align: center;
	font-family: "Cinzel", serif;
	font-size: .68rem;
	letter-spacing: .3em;
	text-indent: .3em;
	text-transform: uppercase;
	color: rgba(255, 233, 168, .65);
}

.toa-count b {
	color: var(--toa-gold);
	font-weight: 600;
}


/* ==========================================================================
   13  Lightbox chrome
   ========================================================================== */

.mfp-bg {
	background: radial-gradient(circle at 50% 42%, rgba(58, 10, 24, .9) 0%, var(--toa-void) 68%);
	opacity: 0;
	transition: opacity .35s ease;
}

.mfp-bg.mfp-ready {
	opacity: .97;
}

.mfp-bg.mfp-removing {
	opacity: 0;
}

img.mfp-img {
	padding: 14px;
	background: linear-gradient(178deg, rgba(58, 10, 24, .5), rgba(5, 3, 10, .9));
	border: 1px solid rgba(249, 197, 63, .55);
	box-shadow:
		0 0 0 1px rgba(0, 0, 0, .9),
		0 0 60px rgba(249, 197, 63, .18),
		0 40px 100px rgba(0, 0, 0, .9);
}

.mfp-figure::after {
	box-shadow: none;
	background: transparent;
}

.mfp-title,
.mfp-counter {
	font-family: "Cinzel", serif;
	text-transform: uppercase;
	letter-spacing: .2em;
	color: var(--toa-gold-lite);
}

.mfp-close,
.mfp-arrow {
	color: var(--toa-gold) !important;
	opacity: .75;
	transition: opacity .25s ease, transform .25s var(--toa-ease-out), filter .25s ease;
}

.mfp-close:hover,
.mfp-arrow:hover,
.mfp-close:focus-visible,
.mfp-arrow:focus-visible {
	opacity: 1;
	filter: drop-shadow(0 0 12px rgba(249, 197, 63, .8));
	transform: scale(1.1);
}

/* Zoom-in transition, enabled by the `zoom` option in JS. */
.mfp-zoom-in .mfp-figure {
	opacity: 0;
	transform: scale(.9);
	transition: all .3s var(--toa-ease-out);
}

.mfp-zoom-in.mfp-ready .mfp-figure {
	opacity: 1;
	transform: scale(1);
}

.mfp-zoom-in.mfp-removing .mfp-figure {
	opacity: 0;
	transform: scale(.9);
}


/* ==========================================================================
   14  Reveal on scroll / tilt / sheen

   Both classes are added by JS only, so with scripting off every element
   stays visible and untransformed.
   ========================================================================== */

.toa-reveal {
	opacity: 0;
	transform: translateY(28px);
	transition:
		opacity .75s ease,
		transform .9s var(--toa-ease-out);
	will-change: opacity, transform;
}

.toa-reveal.is-in {
	opacity: 1;
	transform: none;
}

/* Once revealed, drop the hint so long panels are not holding hundreds of
   composited layers alive. */
.toa-reveal.is-settled {
	will-change: auto;
	transition: none;
}

/* Pointer-tracked tilt. --toa-rx/--toa-ry are written by JS. */
.toa-tilt {
	transform:
		perspective(900px) rotateX(var(--toa-rx, 0deg)) rotateY(var(--toa-ry, 0deg));
	transition: transform .5s var(--toa-ease-out);
	transform-style: preserve-3d;
}

.toa-tilt.is-tilting {
	transition: transform .12s linear;
}

/* Gold specular that follows the cursor across a tilted surface.

   This is a real injected <span>, NOT a ::after. Both tilt targets already own
   both their pseudo-elements: `#vendors .vendorgrid a` uses ::before/::after for
   the frame drawn in from the corners, and — the one that actually broke —
   `.image__square:after` is the padding-bottom aspect-ratio hack that gives that
   box its entire height. Overwriting it with `position:absolute` collapsed every
   artist credit card to 0px tall and hid the images. */
.toa-glow {
	position: absolute;
	inset: 0;
	z-index: 5;
	pointer-events: none;
	opacity: 0;
	background: radial-gradient(closest-side circle at var(--toa-mx) var(--toa-my),
			rgba(255, 246, 216, .3) 0%,
			rgba(249, 197, 63, .12) 42%,
			transparent 72%);
	transition: opacity .35s ease;
}

.toa-tilt:hover > .toa-glow,
.toa-tilt:focus-within > .toa-glow {
	opacity: 1;
}

/* Utility: visually hidden but announced. Bootstrap's .sr-only already exists;
   this is the same contract for elements JS injects. */
.toa-sr {
	position: absolute !important;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}


/* ==========================================================================
   15  Reduced motion, narrow screens, print
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {

	/* Nothing here may hide content — every reveal resolves to its end state. */
	.toa-reveal,
	.toa-reveal.is-in {
		opacity: 1 !important;
		transform: none !important;
		transition: none !important;
	}

	.toa-embers {
		display: none !important;
	}

	.toa-tilt {
		transform: none !important;
		transition: none !important;
	}

	.toa-glow {
		display: none;
	}

	.toa-scrollcue::after,
	#loader::before,
	.toa-sigil--a,
	.toa-sigil--b,
	#gotovendors,
	.h1_larger.brioso.orange,
	#shiny .slide,
	.hero .hero__content > div::before {
		animation: none !important;
	}

	.h1_larger.brioso.orange {
		background-position: 50% 0 !important;
	}

	/* The base sheet's own decorative loops. */
	.flicker,
	.bloodpulsing,
	.illiglow,
	.illiglow2,
	.intro__logo,
	[class^="bunny-jump"] {
		animation: none !important;
	}

	.vendor,
	.vendor .logointro,
	.vendor .vender__content,
	.vendor .vender__content .filigree,
	.vendor .backbutton {
		transition-duration: .01ms !important;
		transition-delay: 0s !important;
	}

	.vendor.is-open .vender__content::after {
		animation: none !important;
		opacity: 0 !important;
	}

	.intro_nav a .button-game-bg-mid::after,
	.backbutton a .button-game-bg-mid::after,
	.gembutton a .button-game-bg-mid::after {
		display: none;
	}

	#loader.toa-ignite,
	#loader.toa-ignite::after {
		animation-duration: .2s !important;
	}

	html {
		scroll-behavior: auto !important;
	}
}

/* Tone the ambient work down where it costs the most and shows the least. */
@media (max-width: 575.98px) {
	.toa-embers {
		opacity: .55;
	}

	.vendor .vender__content,
	.vendorboard .vender__content {
		backdrop-filter: none;
		-webkit-backdrop-filter: none;
	}

	/* At 375px the eyebrow ran to two lines and orphaned a separator on the
	   first. Tighter tracking keeps it on one. */
	.toa-eyebrow {
		font-size: .55rem;
		letter-spacing: .22em;
		text-indent: .22em;
	}

	#vendors .vendorgrid a::before,
	#vendors .vendorgrid a::after,
	.toa-shade {
		inset: 10px;
	}

	.toa-plate {
		top: 16px;
		right: 16px;
		letter-spacing: .16em;
		text-indent: .16em;
		padding: .45em .6em .4em;
	}
}

/* On touch there is no hover, so the "Enter" chip would never appear and the
   resting vignette would never lift. Show the chip and drop the vignette. */
@media (hover: none) {
	.toa-plate {
		opacity: 1;
		transform: none;
	}

	.toa-shade {
		opacity: 0;
	}

	.toa-tilt {
		transform: none !important;
	}
}

@media print {

	.toa-embers,
	.toa-beam,
	.toa-veil,
	.toa-hint,
	.toa-scrollcue,
	#loader {
		display: none !important;
	}

	.toa-reveal {
		opacity: 1 !important;
		transform: none !important;
	}

	.vendor {
		position: static !important;
		visibility: visible !important;
		opacity: 1 !important;
		height: auto !important;
		page-break-before: always;
	}
}


/* ==========================================================================
   16  Glitz pass — additive light only
   Everything in this section ADDS glow, sparkle or sweep on top of what is
   already there; nothing repositions or removes content. Every animation here
   is switched off wholesale in the reduced-motion block at the bottom.

   Two hard-won rules from earlier in this file are obeyed throughout:
   keyframes REPLACE a property, so every filter keyframe re-states the full
   composed filter list; and no rule below animates a property that a base-
   stylesheet animation already animates on the same element (fireFlicker owns
   `filter` on .intro__logo and .flicker wares, so those get box-shadow or
   nothing).
   ========================================================================== */

/* --- Sunwell god-rays behind the hero crest (element injected by JS) ------ */
.toa-rays {
	position: absolute;
	left: 50%;
	top: 0;
	width: min(100%, 820px);
	aspect-ratio: 1 / 1;
	transform: translate(-50%, -26%);
	pointer-events: none;
	z-index: 0;
	opacity: .8;
	mix-blend-mode: screen;
	background: repeating-conic-gradient(from 0deg,
			rgba(249, 197, 63, .22) 0deg 5deg,
			rgba(249, 197, 63, 0) 5deg 17deg);
	-webkit-mask-image: radial-gradient(closest-side, #000 0%, rgba(0, 0, 0, .5) 46%, transparent 72%);
	mask-image: radial-gradient(closest-side, #000 0%, rgba(0, 0, 0, .5) 46%, transparent 72%);
	animation: toa-rays 150s linear infinite;
}

/* transform is composed INTO the keyframes: a bare rotate() would replace the
   centring translate — the exact bug the old bloom disc had. */
@keyframes toa-rays {
	from {
		transform: translate(-50%, -26%) rotate(0deg);
	}

	to {
		transform: translate(-50%, -26%) rotate(360deg);
	}
}

/* --- Aurora drifting behind the booth board (elements injected by JS) ----- */
#vendors {
	position: relative;
	isolation: isolate;
	/* keep the blend inside the booth */
}

#vendors .vendorboard {
	position: relative;
	z-index: 1;
}

#vendors > .toa-aurora {
	position: absolute;
	width: 44vw;
	max-width: 640px;
	aspect-ratio: 1 / 1;
	border-radius: 50%;
	filter: blur(70px);
	mix-blend-mode: screen;
	pointer-events: none;
	z-index: 0;
	opacity: .5;
}

.toa-aurora--a {
	left: 4%;
	top: 4%;
	background: radial-gradient(circle, rgba(249, 197, 63, .32) 0%, rgba(142, 18, 48, .12) 58%, transparent 74%);
	animation: toa-aurora-a 46s var(--toa-ease-in-out) infinite alternate;
}

.toa-aurora--b {
	right: 5%;
	bottom: 6%;
	background: radial-gradient(circle, rgba(203, 51, 75, .3) 0%, rgba(249, 197, 63, .1) 55%, transparent 74%);
	animation: toa-aurora-b 58s var(--toa-ease-in-out) infinite alternate;
}

/* Drift stays well inside the section so transformed bounds can never grow
   the scrollable area. */
@keyframes toa-aurora-a {
	from {
		transform: translate(0, 0) scale(1);
	}

	to {
		transform: translate(3vw, 5vh) scale(1.12);
	}
}

@keyframes toa-aurora-b {
	from {
		transform: translate(0, 0) scale(1.08);
	}

	to {
		transform: translate(-3vw, -4vh) scale(.94);
	}
}

/* --- Filigree corners breathe like warm metal ----------------------------- */
.hero .filigree,
.vender__content .filigree {
	animation: toa-fil-breathe 7s var(--toa-ease-in-out) infinite;
}

/* stagger so the four corners never pulse in lockstep */
.filigree_tr {
	animation-delay: -1.8s;
}

.filigree_br {
	animation-delay: -3.5s;
}

.filigree_bl {
	animation-delay: -5.2s;
}

@keyframes toa-fil-breathe {

	0%,
	100% {
		filter: drop-shadow(0 0 7px rgba(249, 197, 63, .22));
	}

	50% {
		filter: drop-shadow(0 0 18px rgba(249, 197, 63, .5));
	}
}

/* --- Panel crests get a slow living bloom ---------------------------------
   Safe to animate filter here: nothing in the base sheet animates these (the
   hero crest's fireFlicker is .intro__logo, a different element). Both shadows
   from the static rule are re-stated in full. */
.logointro img {
	animation: toa-crest-breathe 9s var(--toa-ease-in-out) infinite;
}

@keyframes toa-crest-breathe {

	0%,
	100% {
		filter: drop-shadow(0 10px 34px rgba(0, 0, 0, .85)) drop-shadow(0 0 34px rgba(249, 197, 63, .18));
	}

	50% {
		filter: drop-shadow(0 10px 34px rgba(0, 0, 0, .85)) drop-shadow(0 0 52px rgba(249, 197, 63, .4));
	}
}

/* --- A hearth-glow breathing behind every divider crest -------------------
   ::after is free here — the old travelling glint was removed outright, so the
   pseudo-element is unclaimed by either sheet. Opacity-only animation keeps
   this cheap even with thirty dividers on one panel. z-index 0 on .divider
   makes it a stacking context so the -1 glow sits between the divider's own
   background art and the crest image. */
.divider {
	position: relative;
	z-index: 0;
}

.divider::after {
	content: "";
	position: absolute;
	left: 50%;
	top: 50%;
	width: min(460px, 74%);
	height: 130%;
	transform: translate(-50%, -50%);
	background: radial-gradient(closest-side, rgba(249, 197, 63, .3) 0%, rgba(203, 51, 75, .14) 52%, transparent 76%);
	z-index: -1;
	pointer-events: none;
	animation: toa-soft-breathe 7.5s var(--toa-ease-in-out) infinite;
}

@keyframes toa-soft-breathe {

	0%,
	100% {
		opacity: .5;
	}

	50% {
		opacity: 1;
	}
}

/* The gem rule under the LARGEST titles breathes on the same curve. Kept to
   .h1_larger so it stays ~a dozen elements, not all eighty-odd headings. */
p.h1.h1_larger.brioso.text-center::after,
h2.h1.h1_larger.brioso.text-center::after {
	animation: toa-soft-breathe 5.5s var(--toa-ease-in-out) infinite;
}

/* --- The active carousel gem pulses like a socketed jewel ----------------- */
.toa-slider__rail a.active::after,
.phoenixslidercontrols a.active::after,
.dragons__controls a.active::after,
.squishies__controls a.active::after,
.covenantcompamions__controls a.active::after {
	animation: toa-gem-glow 4s var(--toa-ease-in-out) infinite;
}

@keyframes toa-gem-glow {

	0%,
	100% {
		box-shadow: 0 0 12px rgba(249, 197, 63, .45), inset 0 0 12px rgba(249, 197, 63, .16);
	}

	50% {
		box-shadow: 0 0 26px rgba(249, 197, 63, .85), inset 0 0 22px rgba(249, 197, 63, .38);
	}
}

/* --- Wares flash like a looted item on hover -------------------------------
   box-shadow, NOT filter: several wares run the base sheet's fireFlicker-class
   animations on filter, and two animations fighting over one property ends
   badly. The keyframe ENDS on the exact static :hover shadow from section 11,
   so the one-shot settles seamlessly. */
.popup-img:hover,
.popup-img:focus-visible {
	animation: toa-ware-flash .55s var(--toa-ease-out);
}

@keyframes toa-ware-flash {
	0% {
		box-shadow:
			0 0 0 2px rgba(255, 246, 216, .95),
			0 0 38px rgba(249, 197, 63, .8),
			0 26px 60px -26px rgba(0, 0, 0, .95);
	}

	100% {
		box-shadow:
			0 0 0 1px rgba(249, 197, 63, .7),
			0 0 26px rgba(249, 197, 63, .35),
			0 26px 60px -26px rgba(0, 0, 0, .95);
	}
}

/* --- Lightbox: the frame blooms once as the image lands ------------------- */
.mfp-zoom-in.mfp-ready img.mfp-img {
	animation: toa-lb-bloom .9s var(--toa-ease-out);
}

@keyframes toa-lb-bloom {
	0% {
		box-shadow:
			0 0 0 1px rgba(0, 0, 0, .9),
			0 0 90px rgba(249, 197, 63, .55),
			0 40px 100px rgba(0, 0, 0, .9);
	}

	100% {
		box-shadow:
			0 0 0 1px rgba(0, 0, 0, .9),
			0 0 60px rgba(249, 197, 63, .18),
			0 40px 100px rgba(0, 0, 0, .9);
	}
}

/* --- Jump chips get the same specular sweep as the gilded plates ---------- */
.toa-jump__link {
	position: relative;
	overflow: hidden;
}

.toa-jump__link::after {
	content: "";
	position: absolute;
	top: 0;
	bottom: 0;
	left: -60%;
	width: 45%;
	background: linear-gradient(100deg, transparent 0%, rgba(255, 246, 216, .4) 50%, transparent 100%);
	transform: skewX(-18deg);
	opacity: 0;
	pointer-events: none;
}

.toa-jump__link:hover::after,
.toa-jump__link:focus-visible::after {
	animation: toa-sweep .7s var(--toa-ease-out) forwards;
}

/* --- Glitz pass: small screens --------------------------------------------
   blur(70px) over half the viewport is real GPU work on a phone, and the rays
   read as noise at that size. */
@media (max-width: 575.98px) {
	#vendors > .toa-aurora {
		display: none;
	}

	.toa-rays {
		opacity: .35;
	}
}

/* --- Glitz pass: reduced motion -------------------------------------------
   Nothing here may hide content; every target keeps its static styling. */
@media (prefers-reduced-motion: reduce) {

	.toa-rays,
	#vendors > .toa-aurora {
		display: none !important;
	}

	.hero .filigree,
	.vender__content .filigree,
	.logointro img,
	.divider::after,
	p.h1.h1_larger.brioso.text-center::after,
	h2.h1.h1_larger.brioso.text-center::after,
	.toa-slider__rail a.active::after,
	.phoenixslidercontrols a.active::after,
	.dragons__controls a.active::after,
	.squishies__controls a.active::after,
	.covenantcompamions__controls a.active::after,
	.popup-img:hover,
	.popup-img:focus-visible,
	img.mfp-img,
	.toa-jump__link::after {
		animation: none !important;
	}
}


/* ==========================================================================
   17  Interactive pass — things that answer the visitor
   Tooltip, per-stall gallery chrome, crest flare, shiny countdown. All
   elements here are injected by JS with aria-hidden where decorative; the
   reduced-motion block at the bottom stills anything that moves.
   ========================================================================== */

/* --- WoW-style item tooltip ------------------------------------------------
   Sits just below magnific's layers (1042+) so an open lightbox always covers
   it. pointer-events none: it must never trap the cursor it follows. */
.toa-tip {
	position: fixed;
	z-index: 1041;
	max-width: 300px;
	padding: .55em .85em .6em;
	background: linear-gradient(178deg, rgba(24, 10, 18, .97) 0%, rgba(5, 3, 10, .97) 100%);
	border: 1px solid rgba(249, 197, 63, .75);
	border-radius: 8px;
	box-shadow:
		0 0 0 1px rgba(0, 0, 0, .9),
		0 0 22px rgba(249, 197, 63, .26),
		0 14px 30px rgba(0, 0, 0, .8);
	pointer-events: none;
	opacity: 0;
	transform: translateY(4px) scale(.97);
	transition: opacity .16s ease, transform .2s var(--toa-ease-out);
}

.toa-tip.is-on {
	opacity: 1;
	transform: none;
}

.toa-tip__name {
	display: block;
	font-family: "scrivano", serif;
	font-weight: 700;
	font-size: 1rem;
	line-height: 1.3;
	color: var(--toa-gold);
	text-shadow: 0 0 10px rgba(249, 197, 63, .4);
}

.toa-tip__hint {
	display: block;
	margin-top: .4em;
	font-family: "Cinzel", serif;
	font-size: .56rem;
	line-height: 1;
	letter-spacing: .28em;
	text-indent: .28em;
	text-transform: uppercase;
	color: rgba(255, 233, 168, .6);
}

/* --- Crest flare (easter egg) ---------------------------------------------- */
.toa-crest-flare {
	position: fixed;
	z-index: var(--toa-z-beam);
	width: 60vmin;
	height: 60vmin;
	border-radius: 50%;
	pointer-events: none;
	mix-blend-mode: screen;
	background: radial-gradient(circle,
			rgba(255, 246, 216, .9) 0%,
			rgba(249, 197, 63, .45) 26%,
			rgba(203, 51, 75, .18) 48%,
			transparent 70%);
	animation: toa-crest-flare .9s var(--toa-ease-out) forwards;
}

@keyframes toa-crest-flare {
	0% {
		opacity: 0;
		transform: translate(-50%, -50%) scale(.25);
	}

	18% {
		opacity: 1;
	}

	100% {
		opacity: 0;
		transform: translate(-50%, -50%) scale(1.6);
	}
}

/* --- Shiny countdown teaser -------------------------------------------------
   Arcane violet on purpose: everything else on the page is gold and crimson,
   so the one crystal-flavoured thing on the page reads as OTHER at a glance. */
.toa-teaser {
	margin: 1.4em auto 0;
	max-width: 780px;
	padding: .85em 1em .8em;
	text-align: center;
	font-family: "Cinzel", "scrivano", serif;
	font-weight: 600;
	font-size: .66rem;
	line-height: 1.6;
	letter-spacing: .26em;
	text-indent: .26em;
	text-transform: uppercase;
	color: var(--toa-gold-lite);
	border: 1px solid rgba(197, 107, 255, .5);
	border-radius: 10px;
	background: radial-gradient(120% 100% at 50% 0%, rgba(197, 107, 255, .13) 0%, rgba(5, 3, 10, .6) 70%);
	box-shadow: 0 0 24px rgba(197, 107, 255, .2), inset 0 0 30px rgba(197, 107, 255, .08);
	animation: toa-soft-breathe 6s var(--toa-ease-in-out) infinite;
}

.toa-teaser b {
	font-weight: 600;
	color: #e2b8ff;
	letter-spacing: .3em;
}

/* --- Interactive pass: reduced motion -------------------------------------- */
@media (prefers-reduced-motion: reduce) {

	.toa-tip {
		transition: none;
	}

	.toa-teaser {
		animation: none !important;
	}

	.toa-crest-flare {
		display: none !important;
	}
}


/* ==========================================================================
   18  Utility & payoff pass
   Back-to-top feather, Belore's hour sky, image shimmer-in, the Satchel
   (wishlist), and lightbox add-button. All elements injected by JS.
   ========================================================================== */

/* [hidden] must always win, because the classes below set display. */
.toa-satchel[hidden],
.toa-satchel-chip[hidden],
.toa-mfp-add[hidden] {
	display: none !important;
}

/* --- Back-to-the-top feather ---------------------------------------------- */
.toa-top {
	position: fixed;
	right: 16px;
	bottom: 64px;
	z-index: var(--toa-z-chrome);
	width: 46px;
	height: 46px;
	padding: 0;
	border-radius: 50%;
	border: 1px solid rgba(249, 197, 63, .55);
	background: radial-gradient(120% 120% at 50% 20%, rgba(58, 10, 24, .92) 0%, rgba(5, 3, 10, .96) 100%);
	box-shadow: 0 0 0 1px rgba(0, 0, 0, .85), 0 0 18px rgba(249, 197, 63, .22), 0 10px 24px rgba(0, 0, 0, .7);
	color: var(--toa-gold);
	cursor: pointer;
	opacity: 0;
	transform: translateY(10px);
	pointer-events: none;
	transition: opacity .3s ease, transform .35s var(--toa-ease-out), box-shadow .3s ease, color .3s ease;
}

.toa-top.is-on {
	opacity: 1;
	transform: none;
	pointer-events: auto;
}

.toa-top:hover,
.toa-top:focus-visible {
	color: var(--toa-sunwell);
	box-shadow: 0 0 0 1px rgba(0, 0, 0, .85), 0 0 26px rgba(249, 197, 63, .5), 0 12px 26px rgba(0, 0, 0, .8);
}

.toa-top svg {
	display: block;
	margin: 0 auto;
}

.toa-top svg path {
	fill: none;
	stroke: currentColor;
	stroke-width: 1.6;
	stroke-linecap: round;
}

/* --- Belore's hour: the hero sky follows the visitor's clock ---------------

   Four photographs of the same plaza at four hours, rather than one image
   recoloured four ways — the gradient washes this replaced could push a hue
   but never change the light itself.

   Costs one background per visit, not four: a browser only fetches the image
   from the rule that actually matches, and exactly one hour class is ever set.
   The class is written by an inline snippet in <head> so the fetch starts
   before the main script has even loaded.

   `.hero`'s own eversong.jpg stays as the floor: with no hour class on <html>
   — scripting off — none of this applies and the original sky shows. */
.hero {
	z-index: 0;
	/* stacking context for the hero's other injected layers (rays, aurora) */
}

html.toa-dawn .hero {
	background-image: url("../../assets/images/sky_dawn.jpg");
}

html.toa-day .hero {
	background-image: url("../../assets/images/sky_day.jpg");
}

html.toa-dusk .hero {
	background-image: url("../../assets/images/sky_dusk.jpg");
}

html.toa-night .hero {
	background-image: url("../../assets/images/sky_night.jpg");
}

/* --- Shimmer-in for lazy wares ---------------------------------------------
   Painted on the img element itself, so no wrappers and no layout risk; it
   simply shows through until the pixels arrive, then the class is removed. */
.toa-loading {
	background:
		linear-gradient(100deg, rgba(249, 197, 63, .05) 20%, rgba(255, 233, 168, .14) 40%, rgba(249, 197, 63, .05) 60%) 0 0/220% 100% no-repeat,
		rgba(5, 3, 10, .35);
	animation: toa-shimmer 1.6s linear infinite;
}

@keyframes toa-shimmer {
	from {
		background-position: 120% 0;
	}

	to {
		background-position: -120% 0;
	}
}

/* --- The Satchel ------------------------------------------------------------
   Chip above everything including the lightbox (1042+), because items are
   added FROM the lightbox and the count ticking up is the feedback. */
.toa-satchel-chip {
	position: fixed;
	left: 16px;
	bottom: 16px;
	z-index: 1050;
	display: flex;
	align-items: center;
	gap: .55em;
	padding: .6em .95em .55em;
	border-radius: 999px;
	border: 1px solid rgba(249, 197, 63, .6);
	background: linear-gradient(178deg, rgba(24, 10, 18, .96) 0%, rgba(5, 3, 10, .96) 100%);
	color: var(--toa-gold-lite);
	font-family: "Cinzel", serif;
	font-weight: 600;
	font-size: .62rem;
	letter-spacing: .22em;
	text-indent: .22em;
	text-transform: uppercase;
	cursor: pointer;
	box-shadow: 0 0 0 1px rgba(0, 0, 0, .9), 0 0 20px rgba(249, 197, 63, .25), 0 10px 24px rgba(0, 0, 0, .75);
	transition: box-shadow .25s ease, color .25s ease;
}

.toa-satchel-chip:hover,
.toa-satchel-chip:focus-visible {
	color: var(--toa-sunwell);
	box-shadow: 0 0 0 1px rgba(0, 0, 0, .9), 0 0 28px rgba(249, 197, 63, .45), 0 10px 24px rgba(0, 0, 0, .8);
}

.toa-satchel-chip b {
	font-size: .8rem;
	color: var(--toa-gold);
	letter-spacing: 0;
	text-indent: 0;
}

.toa-satchel-chip svg {
	display: block;
}

.toa-satchel-chip svg path {
	fill: none;
	stroke: currentColor;
	stroke-width: 1.5;
	stroke-linecap: round;
	stroke-linejoin: round;
}

.toa-satchel {
	position: fixed;
	left: 16px;
	bottom: 72px;
	z-index: 1051;
	width: min(360px, 92vw);
	max-height: min(520px, 70vh);
	display: flex;
	flex-direction: column;
	padding: 1em 1em .9em;
	border: 1px solid rgba(249, 197, 63, .5);
	border-radius: 12px;
	background: linear-gradient(178deg, rgba(30, 12, 22, .98) 0%, rgba(5, 3, 10, .98) 100%);
	box-shadow: 0 0 0 1px rgba(0, 0, 0, .9), 0 0 34px rgba(249, 197, 63, .18), 0 24px 60px rgba(0, 0, 0, .85);
}

.toa-satchel__title {
	margin: 0 0 .6em;
	font-family: "Cinzel", "scrivano", serif;
	font-weight: 700;
	font-size: .72rem;
	letter-spacing: .3em;
	text-indent: .3em;
	text-transform: uppercase;
	color: var(--toa-gold);
	text-align: center;
}

.toa-satchel__list {
	list-style: none;
	margin: 0;
	padding: 0;
	overflow-y: auto;
	flex: 1 1 auto;
}

.toa-satchel__list li {
	display: flex;
	align-items: baseline;
	gap: .6em;
	padding: .45em .2em;
	border-bottom: 1px solid rgba(249, 197, 63, .14);
}

.toa-satchel__list .n {
	flex: 1 1 auto;
	font-family: "scrivano", serif;
	font-weight: 700;
	font-size: .92rem;
	line-height: 1.3;
	color: var(--toa-gold-lite);
}

.toa-satchel__list .s {
	flex: 0 1 auto;
	font-family: "Cinzel", serif;
	font-size: .52rem;
	letter-spacing: .16em;
	text-transform: uppercase;
	color: rgba(255, 233, 168, .55);
}

.toa-satchel__list .x {
	flex: 0 0 auto;
	width: 22px;
	height: 22px;
	padding: 0;
	border: 1px solid rgba(203, 51, 75, .5);
	border-radius: 50%;
	background: none;
	color: var(--toa-crimson);
	font-size: .7rem;
	line-height: 1;
	cursor: pointer;
}

.toa-satchel__list .x:hover,
.toa-satchel__list .x:focus-visible {
	background: rgba(203, 51, 75, .25);
	color: #fff;
}

.toa-satchel__empty {
	margin: .4em 0 .6em;
	font-size: .82rem;
	font-style: italic;
	text-align: center;
	color: rgba(255, 246, 216, .6);
}

.toa-satchel__row {
	display: flex;
	gap: .5em;
	margin-top: .8em;
}

.toa-satchel__row button {
	flex: 1 1 auto;
	padding: .55em .4em .5em;
	border-radius: 8px;
	border: 1px solid rgba(249, 197, 63, .5);
	background: rgba(5, 3, 10, .6);
	color: var(--toa-gold-lite);
	font-family: "Cinzel", serif;
	font-weight: 600;
	font-size: .56rem;
	letter-spacing: .18em;
	text-indent: .18em;
	text-transform: uppercase;
	cursor: pointer;
	transition: border-color .25s ease, box-shadow .25s ease, color .25s ease;
}

.toa-satchel__row button:hover,
.toa-satchel__row button:focus-visible {
	border-color: var(--toa-gold);
	color: var(--toa-sunwell);
	box-shadow: 0 0 14px rgba(249, 197, 63, .3);
}

/* --- Add-to-satchel button in the lightbox's bottom bar -------------------- */
.toa-mfp-add {
	display: table;
	margin: .55em auto 0;
	padding: .5em .95em .45em;
	border-radius: 999px;
	border: 1px solid rgba(249, 197, 63, .55);
	background: rgba(5, 3, 10, .72);
	color: var(--toa-gold);
	font-family: "Cinzel", serif;
	font-weight: 600;
	font-size: .6rem;
	letter-spacing: .2em;
	text-indent: .2em;
	text-transform: uppercase;
	cursor: pointer;
	transition: border-color .25s ease, color .25s ease, box-shadow .25s ease;
}

.toa-mfp-add:hover,
.toa-mfp-add:focus-visible {
	border-color: var(--toa-gold);
	color: var(--toa-sunwell);
	box-shadow: 0 0 16px rgba(249, 197, 63, .35);
}

.toa-mfp-add.is-in {
	border-color: rgba(126, 211, 150, .6);
	color: #b6f0c5;
}

/* --- Utility pass: small screens & reduced motion --------------------------- */
@media (max-width: 575.98px) {
	.toa-top {
		right: 12px;
		bottom: 58px;
		width: 42px;
		height: 42px;
	}

	.toa-satchel {
		left: 10px;
		right: 10px;
		width: auto;
	}
}

@media (prefers-reduced-motion: reduce) {
	.toa-loading {
		animation: none !important;
		background: rgba(5, 3, 10, .35);
	}

	.toa-top {
		transition: none;
	}
}


/* --- Ware rune: add to satchel straight from the shelf ----------------------
   One button per ware, permanently visible, pinned by JS to the ware's own
   top-right corner. Round + a plus glyph reads "add" at a glance; in-satchel
   items flip it to a green-gold check. z-index stays low single digits so
   magnific (1042+) and the satchel chip both cover it. */
.toa-addhost.is-rel {
	position: relative;
}

.toa-ware-add {
	position: absolute;
	z-index: 3;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 28px;
	height: 28px;
	padding: 0;
	border-radius: 50%;
	border: 1px solid rgba(249, 197, 63, .7);
	background: radial-gradient(120% 120% at 50% 25%, rgba(40, 16, 26, .93) 0%, rgba(5, 3, 10, .95) 100%);
	color: var(--toa-gold);
	cursor: pointer;
	box-shadow: 0 0 0 1px rgba(0, 0, 0, .8), 0 0 10px rgba(249, 197, 63, .25), 0 4px 10px rgba(0, 0, 0, .5);
	/* Held back a little at rest: there are 186 of these on the page, and at
	   full strength they read as clutter instead of affordance. */
	opacity: .68;
	transition: opacity .18s ease, transform .2s var(--toa-ease-out), color .2s ease, border-color .2s ease, box-shadow .2s ease;
}

/* Full strength once the visitor is anywhere near the ware. */
.toa-addhost:hover .toa-ware-add,
.toa-ware-add:hover,
.toa-ware-add:focus-visible {
	opacity: 1;
}

.toa-ware-add:hover,
.toa-ware-add:focus-visible {
	color: var(--toa-sunwell);
	border-color: var(--toa-gold);
	transform: scale(1.15);
	box-shadow: 0 0 0 1px rgba(0, 0, 0, .85), 0 0 20px rgba(249, 197, 63, .6), 0 6px 14px rgba(0, 0, 0, .7);
}

/* Coarse pointers get a bigger target; JS reads the rendered width, so the
   corner maths follows this automatically. */
@media (hover: none) and (pointer: coarse) {
	.toa-ware-add {
		width: 34px;
		height: 34px;
		opacity: .85;
	}
}

.toa-ware-add svg {
	display: block;
	margin: 0 auto;
}

.toa-ware-add svg path {
	fill: none;
	stroke: currentColor;
	stroke-width: 1.7;
	stroke-linecap: round;
	stroke-linejoin: round;
}

.toa-ware-add .p-chk {
	display: none;
}

/* An item already in the satchel is information, not an invitation — it stays
   at full strength whether or not the visitor is hovering. */
.toa-ware-add.is-in {
	opacity: 1;
	color: #b6f0c5;
	border-color: rgba(126, 211, 150, .7);
}

.toa-ware-add.is-in .p-plus {
	display: none;
}

.toa-ware-add.is-in .p-chk {
	display: block;
}

@media (prefers-reduced-motion: reduce) {
	.toa-ware-add {
		transition: none;
	}
}


/* --- Shop hint under the booth heading --------------------------------------
   A measured line width so it reads as a caption, not a paragraph slab. */
.toa-shop-hint {
	max-width: 860px;
	margin: .3em auto 0;
}

/* An inline replica of the ware rune, so the instruction points at the exact
   thing the visitor will see. The parent heading is gradient-clipped text
   (.brioso.red), which inherits transparent text-fill into children — the
   explicit -webkit-text-fill-color here is what keeps the plus gold. */
.toa-plus-demo {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 1.3em;
	height: 1.3em;
	margin: 0 .12em;
	border-radius: 50%;
	border: 1px solid rgba(249, 197, 63, .75);
	background: radial-gradient(120% 120% at 50% 25%, rgba(40, 16, 26, .96) 0%, rgba(5, 3, 10, .97) 100%);
	color: var(--toa-gold);
	-webkit-text-fill-color: var(--toa-gold);
	font-family: "krete", serif;
	font-weight: 700;
	font-size: .78em;
	line-height: 1;
	transform: translateY(-.08em);
	box-shadow: 0 0 10px rgba(249, 197, 63, .35);
}


/* --- Satchel gain: an ember flies to the bag, the bag answers ---------------
   The mote rides above everything (adds can start inside the lightbox at
   z1042+); the chip then pops and throws an expanding gold ring. */
.toa-fly {
	position: fixed;
	z-index: 1052;
	width: 14px;
	height: 14px;
	margin: -7px 0 0 -7px;
	border-radius: 50%;
	pointer-events: none;
	background: radial-gradient(circle, var(--toa-sunwell) 0%, var(--toa-gold) 45%, rgba(249, 197, 63, 0) 75%);
	box-shadow: 0 0 12px rgba(249, 197, 63, .8), 0 0 30px rgba(249, 197, 63, .4);
}

.toa-satchel-chip::after {
	content: "";
	position: absolute;
	inset: -3px;
	border-radius: inherit;
	border: 2px solid rgba(255, 246, 216, .9);
	opacity: 0;
	pointer-events: none;
}

.toa-satchel-chip.is-gained {
	animation: toa-chip-gain .7s var(--toa-ease-out);
}

.toa-satchel-chip.is-gained::after {
	animation: toa-chip-ring .7s var(--toa-ease-out);
}

@keyframes toa-chip-gain {
	0% {
		transform: scale(1);
	}

	28% {
		transform: scale(1.22);
		box-shadow: 0 0 0 1px rgba(0, 0, 0, .9), 0 0 36px rgba(249, 197, 63, .75), 0 10px 24px rgba(0, 0, 0, .8);
	}

	60% {
		transform: scale(.96);
	}

	100% {
		transform: scale(1);
	}
}

@keyframes toa-chip-ring {
	0% {
		opacity: .95;
		transform: scale(.7);
	}

	100% {
		opacity: 0;
		transform: scale(1.75);
	}
}

@media (prefers-reduced-motion: reduce) {

	.toa-fly {
		display: none !important;
	}

	.toa-satchel-chip.is-gained,
	.toa-satchel-chip.is-gained::after {
		animation: none !important;
	}
}


/* ==========================================================================
   19  Pick-A-Polymorph — the warm-up minigame

   The five bunnies already bounce on their own (base sheet, .bunny-jump-N,
   which owns their transform). So the shuffle moves their COLUMN instead of
   the image: the bounce keeps running untouched while the seats slide, and
   nothing here ever fights those keyframes.
   ========================================================================== */

.toa-poly {
	position: relative;
}

/* The seat is the column. Transforming a flex item moves nothing else.

   Scoped to .is-shuffling for two reasons: seats have no business animating
   the rest of the time, and these columns are also .toa-reveal elements —
   `.toa-reveal.is-settled { transition: none }` deliberately strips their
   transition once revealed, and would otherwise win on specificity and leave
   the bunnies teleporting between arrangements instead of sliding. */
.toa-poly.is-shuffling .toa-poly__seat {
	z-index: 2;
	transition: transform .26s ease-in-out;
}

/* Armed: the squares invite a pick. */
.toa-poly.is-armed .toa-poly__hit {
	cursor: pointer;
}

.toa-poly.is-armed .toa-poly__hit:hover img,
.toa-poly.is-armed .toa-poly__hit:focus-visible img {
	filter: drop-shadow(0 0 12px rgba(249, 197, 63, .9)) drop-shadow(0 0 26px rgba(249, 197, 63, .45));
}

.toa-poly__hit:focus-visible {
	outline: 2px solid var(--toa-gold);
	outline-offset: 4px;
	border-radius: 10px;
}

/* Out of the running: polymorphed back into an ordinary rabbit. The bounce is
   cancelled rather than paused, so nobody is left frozen mid-hop. */
.toa-poly__seat.is-out img {
	animation: none;
	filter: grayscale(1) brightness(.52) contrast(.92);
	opacity: .85;
	transition: filter .45s ease, opacity .45s ease;
}

/* The winner sits above its own reveal, so Luneth rises from behind it. */
.toa-poly__seat.is-win {
	z-index: 6;
}

.toa-poly__pop {
	position: absolute;
	z-index: 5;
	/* JS sets left/top to the winning bunny; this anchors the art's bottom
	   centre there. Kept on the wrapper so the keyframes below are free to
	   own the image's own transform. */
	transform: translate(-50%, -100%);
	pointer-events: none;
}

.toa-poly__luneth {
	display: block;
	/* Deliberately modest: the row grows by roughly this image's height on a
	   win, and a 320px portrait made that jump startling. */
	width: clamp(150px, 17vw, 235px);
	height: auto;
	transform-origin: 50% 100%;
	filter: drop-shadow(0 16px 26px rgba(0, 0, 0, .7));
}

.toa-poly__pop.is-in .toa-poly__luneth {
	animation: toa-poly-rise .85s var(--toa-ease-out) both;
}

@keyframes toa-poly-rise {
	0% {
		opacity: 0;
		transform: translateY(30%) scale(.5);
	}

	55% {
		opacity: 1;
	}

	100% {
		opacity: 1;
		transform: translateY(0) scale(1);
	}
}

/* Verdict: a gilded shout plus the line that says what to do about it.
   The block reserves a line's height so the button above never jumps. */
.toa-poly__verdict {
	min-height: 1.9em;
	margin: 1.1rem 0 0;
}

/* .h1_larger.brioso.orange earns the specular sweep — the same treatment the
   prize titles get, which is exactly the register a win wants. */
.toa-poly__shout {
	margin: 0 0 .15em;
	line-height: 1.1;
	/* .h1_larger only reaches 4rem from 1024px up; below that the verdict was
	   rendering at the same 24px as its own subtitle.

	   !important is not decoration here: site.main.css carries a blanket
	   `h1, .h1 { font-size: 1.5rem !important }` under 576px, which outranks
	   even an inline style, so nothing weaker can answer it. Kept to this one
	   class. The .h1 class stays on the element because the heading ornament
	   (p.h1.h1_larger.brioso.text-center::after) hangs off it. */
	font-size: clamp(1.9rem, 6.5vw, 4rem) !important;
}

/* Empty between rounds, and an empty h1_larger would hold open a 4rem gap. */
.toa-poly__shout:empty {
	display: none;
}

.toa-poly__say {
	margin: 0;
}

@media (prefers-reduced-motion: reduce) {

	.toa-poly.is-shuffling .toa-poly__seat {
		transition: none;
	}

	.toa-poly__pop.is-in .toa-poly__luneth {
		animation: none;
	}

	.toa-poly__seat.is-out img {
		transition: none;
	}
}


/* ==========================================================================
   20  Backdrops — new plaza photography per stall

   The base sheet gives every stall a backdrop; these reassign them. Each
   selector carries the base sheet's own id specificity plus `html`, so they
   win on the cascade rather than on !important.

   Deliberately re-encoded to 1600px wide: every one of these loads at page
   load, not on open (the panels are laid out from the start, merely hidden),
   so a backdrop's weight is paid by every visitor whether or not they ever
   walk into that stall. */

/* Dark market — Luneth's Tenacious Tapestries. (The booth wears the same
   backdrop; see the note at the end of this section for why it lives in the
   markup instead.) */
html #luneth {
	background-image: url("../../assets/images/silvermoon_market_dark.jpg");
}

/* Autumn gardens — Gladewind, Starweaver, and Randred's Solaris Sunworks. */
html #gladewind,
html #starweaver,
html #solaris {
	background-image: url("../../assets/images/silvermoon3.jpg");
}

/* Twilight spires — Pick-A-Polymorph and the Featured Items. */
html #polymorph,
html #featured {
	background-image: url("../../assets/images/silvermoon2.jpg");
}

/* Night city — Firion. */
html #firion {
	background-image: url("../../assets/images/silvermoon_dark.jpg");
}

/* The booth's own backdrop is not here: #vendors carries its background-image
   as an inline style attribute in the markup, which outranks any stylesheet
   rule, so it is swapped there. Its sizing already comes from the base sheet. */
