/* Dungeons Fusion landing page — a dig-down story: surface → stone → deepslate → bedrock.
   Light shifts with depth, from torch amber at the top to soul-fire cyan at the bottom; --depth (0..1) is set by site.js. */
:root {
  --bg: #15121a;
  --bg-dirt: #20170f;
  --bg-stone: #1a191d;
  --bg-deep: #131118;
  --bg-bottom: #0c0b0e;
  --panel: #221d26;
  --border: #3b3342;
  --torch: #ffb238;
  --torch-dark: #b8650f;
  --soul: #5ee6df;
  --emerald: #3ddc84;
  --paper: #eee3cf;
  --muted: #ada190;
  --depth: 0;
  --light: color-mix(in oklab, var(--torch), var(--soul) calc(var(--depth) * 100%));
  --block: 32px;
  --s1: 4px; --s2: 8px; --s3: 16px; --s4: 24px; --s5: 32px; --s6: 48px; --s7: 96px;
  --max-w: 1120px;
  --font-pixel: "MC", ui-monospace, monospace;
  --font-body: "Chakra Petch", system-ui, sans-serif;
  color-scheme: dark;
}
@media (min-width: 900px) { :root { --block: 48px; } }

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; scroll-padding-top: 88px; -webkit-text-size-adjust: 100%; }  /* in-page anchor scrolling is eased by site.js (the browser's smooth scroll is too fast) */
body { margin: 0; background: var(--bg); color: var(--paper); font: 400 17px/1.6 var(--font-body); overflow-x: hidden; }
img { max-width: 100%; height: auto; display: block; }
a { color: inherit; }
h1, h2, h3 { margin: 0; font-weight: 400; }
p { margin: 0; text-wrap: pretty; }  /* avoid a single word on the last line */
li { text-wrap: pretty; }
h3, .artifacts__item b, .artifacts__item span, .gear-grid__item b, .gear-grid__item span:not(.gear-grid__icon), .steps__item p, .discord-card p, .rules__card p, .boss__card span { text-wrap: balance; }  /* headings and short card copy: balance lines, never leave one word behind */
code { font-family: var(--font-pixel); font-size: 16px; }
:focus-visible { outline: 2px solid var(--torch); outline-offset: 3px; }
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.skip-link { position: absolute; left: var(--s3); top: -64px; z-index: 50; background: var(--torch); color: #1a1208; padding: var(--s2) var(--s3); font-weight: 600; }
.skip-link:focus { top: var(--s3); }

/* ---------- type ---------- */
h2 { font: 32px/1.25 var(--font-pixel); color: #fff; text-shadow: 3px 3px 0 #000; text-wrap: balance; }
h3 { font: 600 20px/1.3 var(--font-body); color: #fff; }
@media (min-width: 900px) { h2 { font-size: 48px; } }
.chapter__lead { font-size: 20px; line-height: 1.55; color: var(--paper); max-width: 34em; margin-top: var(--s4); }
@media (max-width: 899px) {   /* one-column layout: section headings and leads are centred (owner); lists and cards stay left-aligned */
  .chapter__text { text-align: center; }
  .chapter__lead, .chapter__text > .note { margin-inline: auto; }
  .chapter__text > .status { justify-content: center; }
  .chapter__text > .gate-rules { margin-inline: auto; text-align: left; }
}
.note { color: var(--muted); font-size: 16px; margin-top: var(--s3); max-width: 40em; }
.note--center { text-align: center; margin: var(--s6) auto 0; }
.note code { color: var(--paper); }
.note--more { color: var(--paper); font-size: 18px; }   /* a closing line, not a footnote */
.note--more b { font: 24px/1 var(--font-pixel); font-weight: 400; color: var(--torch); text-shadow: 2px 2px 0 #000; }

/* ---------- buttons ---------- */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--s2); min-height: 48px; padding: var(--s2) var(--s4);
  font: 600 17px/1.2 var(--font-body); text-decoration: none; border: 0; border-radius: 0; white-space: nowrap; transition: transform .12s, filter .12s; }
.btn:active { transform: translateY(2px); }
.btn--primary { background: var(--torch); color: #1f1405; box-shadow: inset 0 -4px 0 var(--torch-dark), inset 0 2px 0 #ffd488; }
.btn--primary:hover { filter: brightness(1.08); }
.btn--outline { background: rgba(10, 8, 12, .55); color: var(--paper); box-shadow: inset 0 0 0 2px var(--border); }
.btn--outline:hover { box-shadow: inset 0 0 0 2px var(--torch); color: #fff; }
.btn--sm { min-height: 40px; padding: var(--s1) var(--s3); font-size: 16px; }
.btn--ip { flex-direction: column; align-items: flex-start; gap: 0; padding: var(--s2) var(--s4) var(--s3); }
.btn--ip .btn__label { font-size: 16px; }
.btn--ip .btn__ip { font: 24px/1.2 var(--font-pixel); }
@media (max-width: 400px) { .btn--ip { width: 100%; } .btn--ip .btn__ip { font-size: 16px; } }  /* 24px overflows at 320–360px; the pixel font is only crisp at multiples of 8, so drop to 16 */
.btn.is-copied { background: var(--emerald); box-shadow: inset 0 -4px 0 #1f8a50; color: #06200f; }
.btn--outline.is-copied { background: rgba(61, 220, 132, .15); color: var(--emerald); box-shadow: inset 0 0 0 2px var(--emerald); }

/* ---------- top bar + Bedrock-style coordinate HUD ---------- */
.topbar { position: fixed; inset: 0 0 auto 0; z-index: 30; display: flex; justify-content: space-between; align-items: flex-start; gap: var(--s3); padding: var(--s3); pointer-events: none; }
.topbar > * { pointer-events: auto; }
.topbar { transition: background .2s, box-shadow .2s; }
.topbar.is-solid { background: rgba(12, 10, 14, .92); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); box-shadow: 0 4px 0 #000; pointer-events: auto; }
.hud { display: flex; flex-wrap: nowrap; padding: var(--s2); background: rgba(0, 0, 0, .45); font: 16px/1 var(--font-pixel); color: #fff; text-shadow: 2px 2px 0 #3f3f3f; }
.hud__coords { white-space: nowrap; }
/* live server status next to the coordinates, pulsing dot */
.hud { align-items: center; gap: 12px; }
.hud__status { display: inline-flex; align-items: center; gap: var(--s2); font: inherit; color: var(--muted); white-space: nowrap; }  /* same font, size and shadow as the coordinates */
.hud__status.is-online { color: var(--paper); }
.hud__status .status__dot { width: 10px; height: 10px; box-sizing: border-box; flex: none; background: var(--muted); }
.hud__status.is-online .status__dot { background: var(--emerald); animation: live 1.6s ease-out infinite; }
.hud__status.is-offline .status__dot { background: #ff5555; }
@keyframes live { 0% { box-shadow: 0 0 0 0 rgba(61, 220, 132, .75); opacity: 1; } 50% { opacity: .35; } 70% { box-shadow: 0 0 0 7px rgba(61, 220, 132, 0); } 100% { box-shadow: 0 0 0 0 rgba(61, 220, 132, 0); opacity: 1; } }
@media (max-width: 639px) { .hud { flex-direction: column; align-items: flex-start; gap: 6px; } }
/* narrow phones: shortened status label (full text stays in the DOM for screen readers); the full 16px label pushes the Play button off-screen */
@media (max-width: 439px) { .hud__status [data-short] { font-size: 0; } .hud__status [data-short]::after { content: attr(data-short); font-size: 16px; } }
@media (max-width: 400px) { .topbar { padding: 12px; gap: var(--s2); } .topbar__actions .btn--sm { padding: var(--s1) 12px; } }
.topbar__actions { display: flex; gap: var(--s2); }
.topbar__actions .btn--outline { display: none; }
@media (min-width: 640px) { .topbar__actions .btn--outline { display: inline-flex; min-height: 40px; padding: var(--s1) var(--s3); font-size: 16px; } }

/* depth gauge on the right (desktop) — the page's own scroll indicator; the browser's native scrollbar is hidden */
.depth-gauge { position: fixed; right: var(--s3); top: 50%; z-index: 20; width: 8px; height: 40vh; transform: translateY(-50%); display: none;
  background: linear-gradient(#5d9c34 0 6%, #6b4a2e 6% 26%, #7b7b7b 26% 52%, #4a4750 52% 94%, #2b2a2d 94%); box-shadow: 0 0 0 2px #000; }
.depth-gauge__marker { position: absolute; left: -10px; width: 28px; height: 4px; top: calc(var(--depth) * 100%); background: var(--light); box-shadow: 0 0 12px var(--light); transform: translateY(-50%); }
@media (min-width: 1100px) { .depth-gauge { display: block; } }
html { scrollbar-width: none; }
html::-webkit-scrollbar, body::-webkit-scrollbar { display: none; width: 0; height: 0; }

/* ---------- hero ---------- */
.hero { position: relative; min-height: 100svh; display: flex; flex-direction: column; justify-content: center; gap: var(--s4); padding: var(--s7) var(--s3) var(--s6); overflow: hidden; background: var(--bg-dirt); isolation: isolate; }
/* herobn.png fills the whole hero, anchored to the right edge: the party and Steve sit on the right, the text on the left */
.hero__bg { position: absolute; inset: 0; z-index: -2; overflow: hidden; }
.hero__art { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 100% 50%; }
@media (max-aspect-ratio: 5 / 4) { .hero__art { object-position: 80% 50%; } }   /* portrait: keep Steve and part of the party */
.hero__bg::after { content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, rgba(21, 14, 9, .95) 0%, rgba(21, 14, 9, .82) 45%, rgba(21, 14, 9, .35) 100%),   /* the original darker veil (owner) */
              linear-gradient(180deg, rgba(21, 14, 9, 0) 55%, var(--bg-dirt) 100%); }
.hero__embers { position: absolute; inset: 0; z-index: -1; width: 100%; height: 100%; }
.hero__content { width: 100%; max-width: var(--max-w); margin: auto auto 0; }   /* auto top margin centres the block; the scroll cue takes the bottom */
.hero__logo { width: min(560px, 100%); filter: drop-shadow(0 6px 0 rgba(0, 0, 0, .55)) drop-shadow(0 0 32px rgba(255, 140, 30, .25)); }
.hero__tagline { font: 16px/1.5 var(--font-pixel); color: var(--torch); margin-top: var(--s4); text-shadow: 2px 2px 0 #000; max-width: 36em; }
.hero__tagline span { display: inline-block; text-wrap: balance; }  /* break between the two halves, never strand one word */
@media (min-width: 900px) { .hero__tagline { max-width: none; white-space: nowrap; } }  /* desktop: tagline on a single line */
.hero__intro { font-size: 20px; line-height: 1.55; max-width: 30em; margin-top: var(--s3); text-shadow: 0 1px 12px rgba(0, 0, 0, .8); }
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--s3); margin-top: var(--s5); align-items: stretch; }
.hero__scroll { position: relative; margin: var(--s5) auto 0; align-self: center; font: 16px/1 var(--font-pixel); color: var(--muted); text-decoration: none; text-shadow: 2px 2px 0 #000; white-space: nowrap; }   /* in the flow (pushed to the bottom by the hero flex), so it can never sit on the port line */
.hero__scroll::after { content: ""; display: block; width: 12px; height: 12px; margin: var(--s2) auto 0; border-right: 4px solid currentColor; border-bottom: 4px solid currentColor; transform: rotate(45deg); animation: bob 1.6s ease-in-out infinite; }
@keyframes bob { 50% { transform: translate(0, 6px) rotate(45deg); } }
@media (max-height: 700px) { .hero__scroll { display: none; } }

.hero__port { margin-top: var(--s4); color: var(--paper); font-size: 16px; text-shadow: 0 1px 8px rgba(0, 0, 0, .8); }
/* the port button beside the IP (owner 26/09): same shape, dark so the IP stays the one orange action; the caption does not
   turn into "Đã sao chép" (the button turns green and the toast says it) so its width never jumps */
.btn--port .btn__cap { font-size: 16px; }
.btn--port .btn__ip { color: var(--torch); }
.btn--port.is-copied .btn__ip { color: var(--emerald); }
@media (max-width: 400px) {   /* phones: IP and port still side by side, the IP takes what is left */
  .hero__actions { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--s2); }
  .hero__actions .btn--ip { width: auto; padding-inline: var(--s3); }
}
@media (max-width: 359px) { .hero__actions .btn--ip { padding-inline: var(--s2); } }   /* 320px: the IP needs 180px of the 288 (measured) */
.hero__port + .status { margin-top: var(--s2); }
@media (max-width: 899px) {   /* phones and portrait tablets: the hero is one centred column */
  .hero__content { text-align: center; }
  .hero__logo { display: block; margin-inline: auto; }
  .hero__tagline, .hero__intro { margin-inline: auto; }
  .hero__actions { justify-content: center; }
  .btn--ip { align-items: center; }
}
.status { display: flex; align-items: center; gap: var(--s2); margin-top: var(--s4); color: var(--muted); font-size: 16px; }
.status__dot { width: 10px; height: 10px; flex: none; background: var(--muted); }
.status.is-online .status__dot { background: var(--emerald); box-shadow: 0 0 10px var(--emerald); animation: pulse 2s ease-in-out infinite; }
.status.is-online { color: var(--paper); }
.status.is-offline .status__dot { background: #ff5555; }
@keyframes pulse { 50% { opacity: .45; } }
.status--lg { font-size: 17px; margin-top: var(--s4); }

/* ---------- block strata (the page's signature) ---------- */
.strata { height: calc(var(--block) * 3); background-repeat: repeat-x; background-size: calc(var(--block) * 32) 100%; image-rendering: pixelated; position: relative; box-shadow: inset 0 -12px 16px -8px rgba(0, 0, 0, .55), inset 0 12px 16px -8px rgba(0, 0, 0, .35); }
.strata--surface { background-image: url(../img/blocks/strata-surface.png); }
.strata--stone { background-image: url(../img/blocks/strata-stone.png); }
.strata--deepslate { background-image: url(../img/blocks/strata-deepslate.png); }
.strata--bedrock { background-image: url(../img/blocks/strata-bedrock.png); }
/* when JS paints a strip onto canvas for the block-breaking effect; the canvas extends below the strip so debris can fall over the next chapter */
.strata--canvas { background: linear-gradient(180deg, #0b0a0f, #121016); z-index: 2; }
.strata__canvas { position: absolute; left: 0; top: -64px; width: 100%; height: calc(100% + 224px); pointer-events: none; image-rendering: pixelated; }  /* extends 64px up for debris flying up and 160px down for debris falling */

/* ---------- chapters ---------- */
.chapter { position: relative; padding: var(--s7) var(--s3); isolation: isolate; overflow: clip; }
.chapter::before { content: ""; position: absolute; inset: 0; z-index: -2; opacity: .07; background-size: calc(var(--block) * 1.5); image-rendering: pixelated; }
.chapter::after { content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: radial-gradient(60% 50% at 85% 35%, color-mix(in oklab, var(--light) 14%, transparent), transparent 70%);
  /* glow fades to 0 at the top and bottom edges so adjacent chapters never meet on a hard line */
  -webkit-mask-image: linear-gradient(transparent, #000 22%, #000 78%, transparent); mask-image: linear-gradient(transparent, #000 22%, #000 78%, transparent); }
.chapter--dirt { background: var(--bg-dirt); }
.chapter--dirt::before { background-image: url(../img/blocks/tile-dirt.png); }
.chapter--stone { background: var(--bg-stone); }
.chapter--stone::before { background-image: url(../img/blocks/tile-stone.png); }
.chapter--deep { background: var(--bg-deep); }
.chapter--deep::before { background-image: url(../img/blocks/tile-deepslate.png); }
.chapter--bedrock { background: var(--bg-bottom); padding-bottom: var(--s6); }
.chapter--bedrock::before { background-image: url(../img/blocks/tile-bedrock.png); opacity: .05; }
.chapter--torch::after { background: radial-gradient(45% 55% at 78% 50%, rgba(255, 150, 40, .22), transparent 70%); animation: torch-flicker 3.2s steps(12) infinite; }
@keyframes torch-flicker { 0%, 100% { opacity: 1; } 30% { opacity: .82; } 55% { opacity: .95; } 80% { opacity: .78; } }
.chapter--soul::after { background: radial-gradient(60% 45% at 50% 40%, rgba(94, 230, 223, .14), transparent 70%); }

.chapter__grid { max-width: var(--max-w); margin: 0 auto; display: grid; gap: var(--s6); align-items: center; }
@media (min-width: 900px) {
  .chapter__grid { grid-template-columns: 1fr 1fr; gap: var(--s7); }
  .chapter__grid--reverse > :first-child { order: 2; }
  .chapter__grid--stack { grid-template-columns: 1fr; gap: var(--s6); }
}

.art-frame { margin: 0; position: relative; box-shadow: 0 0 0 4px #000, 0 0 0 8px var(--border), 0 24px 48px rgba(0, 0, 0, .5); }
.art-frame img { width: 100%; aspect-ratio: 1; object-fit: cover; }
@media (max-width: 899px) {   /* one-column layout: a full-width square art filled the whole phone screen */
  .art-frame { width: 100%; max-width: 440px; margin-inline: auto; }
  .art-frame img { aspect-ratio: 4 / 3; }
}
.art-frame--torch { box-shadow: 0 0 0 4px #000, 0 0 0 8px #6b4a1f, 0 0 64px rgba(255, 150, 40, .28); }

/* ---------- rarity ---------- */
.rarity { display: grid; grid-template-columns: auto 1fr; gap: var(--s5); align-items: center; --tint-active: #e8e8e8; }
.rarity__pedestal { width: 136px; height: 136px; display: grid; place-items: center; background: #0e0c10; box-shadow: 0 0 0 4px #000, 0 0 0 8px var(--tint-active), 0 0 48px color-mix(in oklab, var(--tint-active) 55%, transparent); transition: box-shadow .35s; }
/* one sword per tier, stacked in the same cell; natural size = integer-scaled texture, so no resampling blur */
.rarity__sword { grid-area: 1 / 1; image-rendering: pixelated; filter: drop-shadow(0 0 12px var(--tint-active)); opacity: 0; transition: filter .35s, opacity .18s; }
.rarity__sword.is-shown { opacity: 1; }
.rarity__ladder { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s1); }
.rarity__tier { display: flex; justify-content: space-between; align-items: baseline; gap: var(--s3); padding: var(--s2) var(--s3); background: rgba(0, 0, 0, .3); box-shadow: inset 4px 0 0 var(--border); transition: background .25s, box-shadow .25s; }
.rarity__name { font: 16px/1.5 var(--font-pixel); color: var(--tint); text-shadow: 2px 2px 0 #000; }
.rarity__req { font-size: 16px; line-height: 1.5; color: var(--muted); white-space: nowrap; }   /* same 24px line as the tier name: every row is equally tall */
.rarity__tier.is-active { background: color-mix(in oklab, var(--tint) 14%, rgba(0, 0, 0, .3)); box-shadow: inset 4px 0 0 var(--tint); }
.rarity__tier--top .rarity__name { background: linear-gradient(90deg, #55ffff, #d8ffff, #55ffff) 0 0 / 200% 100%; -webkit-background-clip: text; background-clip: text; color: transparent; text-shadow: none; animation: shimmer 3s linear infinite; }
@keyframes shimmer { to { background-position: -200% 0; } }
@media (max-width: 480px) { .rarity { grid-template-columns: 1fr; justify-items: center; } .rarity__ladder { width: 100%; } }

/* ---------- artifacts ---------- */
.artifacts { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--s3); }
@media (min-width: 640px) { .artifacts { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 900px) { .artifacts { grid-template-columns: repeat(4, 1fr); gap: var(--s4); } }
.artifacts__item, .gear-grid__item { display: grid; align-content: start; justify-items: center; text-align: center; gap: var(--s1); padding: var(--s3) var(--s2) var(--s4); background: var(--panel); box-shadow: inset 0 0 0 2px #000, inset 0 0 0 4px var(--border); }
.artifacts__item img { width: 96px; height: 96px; margin-bottom: var(--s2); transition: transform .2s; }
.artifacts__item:hover img { transform: translateY(-4px) scale(1.06); }
.artifacts__item b, .gear-grid__item b { font-weight: 600; color: #fff; font-size: 17px; line-height: 1.3; }
.artifacts__item span, .gear-grid__item > span { font-size: 16px; color: var(--muted); line-height: 1.4; }

/* ---------- bows / crossbows / weapons / armor (icons: Minecraft Dungeons wiki) ---------- */
.gear-grid { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--s3); }
@media (min-width: 900px) { .gear-grid { gap: var(--s4); } }
.gear-grid__icon { position: relative; display: grid; place-items: center; width: 112px; height: 112px; margin-bottom: var(--s2); }
.gear-grid__icon img { width: 112px; height: 112px; filter: drop-shadow(0 8px 10px rgba(0, 0, 0, .55)); transition: transform .2s; }
.gear-grid__item:hover .gear-grid__icon img { transform: translateY(-4px) scale(1.06); }
.gear-grid__fx { position: absolute; pointer-events: none; opacity: 0; }
.rail-dots { display: none; }
@media (max-width: 639px) {   /* phones: two columns like the artifacts grid. A horizontal rail here stole the page scroll and lost the reader's place. */
  .gear-grid { grid-template-columns: repeat(2, 1fr); }
  .gear-grid__icon, .gear-grid__icon img { width: 84px; height: 84px; }
}
/* pixel dots under a swipe rail (gear rails and the boss rail) */
.rail-dots, .boss__dots { justify-content: center; flex-wrap: wrap; gap: var(--s2); margin-top: var(--s2); }
.rail-dots button, .boss__dots button { width: 24px; height: 24px; padding: 0; border: 0; background: none; display: grid; place-items: center; }
.rail-dots button::before, .boss__dots button::before { content: ""; width: 10px; height: 10px; background: #3a3444; box-shadow: 0 0 0 2px #000; transition: background .2s, transform .2s; }
.rail-dots button.is-active::before, .boss__dots button.is-active::before { background: var(--torch); transform: scale(1.2); box-shadow: 0 0 0 2px #000, 0 0 10px rgba(255, 178, 56, .6); }

/* story: each card is "used" as it comes into view — bows draw and loose an arrow, crossbows fire an exploding bolt
   (the server's own explosion sprite), weapons swing a sweep arc (the server's sweep particle), armour drops on and fills the HUD armour bar */
.motion .gear-grid__item { transition: filter .3s, opacity .3s; }
.motion .gear-grid__item:not(.is-lit) { filter: grayscale(.85) brightness(.55); }
.motion .gear-set--bows .is-hit .gear-grid__icon img { animation: bow-draw .5s ease-out; }
@keyframes bow-draw { 45% { translate: -8px 5px; rotate: -7deg; } 60% { translate: 4px -3px; rotate: 2deg; } }
.gear-set--bows .gear-grid__fx { left: 44%; top: 38%; width: 56px; height: 4px; background: linear-gradient(90deg, transparent, #fff 60%, #ffe27a); rotate: -40deg; transform-origin: left center; }
.motion .gear-set--bows .is-hit .gear-grid__fx { animation: arrow-fly .42s .22s ease-out; }
@keyframes arrow-fly { from { opacity: 1; translate: 0 0; } to { opacity: 0; translate: 110px -92px; } }
.motion .gear-set--crossbows .is-hit .gear-grid__icon img { animation: xbow-kick .4s ease-out; }
@keyframes xbow-kick { 25% { translate: -7px 6px; } }
.gear-set--crossbows .gear-grid__fx { right: -34px; top: -34px; width: 96px; height: 96px; background: url(../img/fx/burst.png) 0 0 / 800% 100%; image-rendering: pixelated;
  filter: sepia(1) saturate(7) hue-rotate(-18deg) brightness(1.15) drop-shadow(0 0 8px rgba(255, 120, 30, .8)); }   /* the sprite is grey: tint it fire orange */
.motion .gear-set--crossbows .is-hit .gear-grid__fx { animation: sprite8 .48s steps(8, jump-none) .12s; }
.motion .gear-set--melee .is-hit .gear-grid__icon img { animation: swing .42s ease-out; }
@keyframes swing { 35% { rotate: -20deg; } 70% { rotate: 8deg; } }
.gear-set--melee .gear-grid__fx { inset: -12px; background: url(../img/fx/sweep.png) 0 0 / 800% 100%; image-rendering: pixelated; filter: drop-shadow(0 0 6px rgba(255, 255, 255, .6)); }
.motion .gear-set--melee .is-hit .gear-grid__fx { animation: sprite8 .36s steps(8, jump-none) .08s; }
@keyframes sprite8 { from { opacity: 1; background-position: 0 0; } to { opacity: 1; background-position: 100% 0; } }
.motion .gear-set--armor .is-hit .gear-grid__icon img { animation: armor-on .46s cubic-bezier(.3, 1.4, .5, 1); }
@keyframes armor-on { from { translate: 0 -30px; scale: 1.12; opacity: .2; } }
/* HUD armour bar (81x9 strips from the server's UI pack, drawn at 3x): fills 2 points per card lit */
.armor-bar { display: none; }
.motion .armor-bar { --px: 3px; display: flex; align-items: center; justify-content: center; gap: var(--s3); margin: 0 auto var(--s2); }
.armor-bar__label { font: 16px/1 var(--font-pixel); color: var(--paper); text-shadow: 2px 2px 0 #000; }
.armor-bar__strip { position: relative; width: calc(81 * var(--px)); height: calc(9 * var(--px)); background: url(../img/fx/armor-empty.png) 0 0 / 100% 100% no-repeat; image-rendering: pixelated; }
.armor-bar__full { position: absolute; left: 0; top: 0; bottom: 0; width: calc((var(--full, 0) * 8 + min(var(--full, 0), 1)) * var(--px)); overflow: hidden; background: url(../img/fx/armor-full.png) 0 0 / calc(81 * var(--px)) 100% no-repeat; image-rendering: pixelated; }   /* no delayed transition: it lagged the half plate and opened a gap (26/09) */
.armor-bar__half { position: absolute; top: 0; left: calc(var(--full, 0) * 8 * var(--px)); width: calc(9 * var(--px)); height: 100%; opacity: var(--half, 0); background: url(../img/fx/armor-half.png) 0 0 / 100% 100% no-repeat; image-rendering: pixelated; }
.armor-bar.is-bump .armor-bar__strip { animation: clunk .3s ease-out; }
@media (max-width: 359px) { .motion .armor-bar { --px: 2px; } }   /* 81 x 3px + label overflowed a 320px screen */

/* ---------- bosses ---------- */
.boss__rail { margin-top: var(--s6); overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x proximity; scrollbar-width: none; padding-bottom: var(--s3); }   /* contain: a swipe here never nudges the page */
.boss__rail::-webkit-scrollbar { display: none; }   /* swipe rail: the native scrollbar is replaced by the pixel dots below */
.boss__dots { display: flex; }
.chapter--boss.is-pinned .boss__dots { display: none; }
.boss__track { list-style: none; margin: 0; padding: 0 var(--s3); display: flex; gap: var(--s4); width: max-content; }
.boss__card { scroll-snap-align: center; width: 240px; flex: none; display: grid; gap: var(--s2); justify-items: center; text-align: center; }
.boss__card img { width: 240px; aspect-ratio: 4 / 3; object-fit: contain; filter: drop-shadow(0 12px 16px rgba(0, 0, 0, .7)); }
.boss__card span { font: 16px/1.3 var(--font-pixel); color: #fff; text-shadow: 2px 2px 0 #000; }
@media (min-width: 900px) {
  .chapter--boss.is-pinned { padding: 0; }
  .chapter--boss.is-pinned .boss__pin { position: sticky; top: 0; height: 100vh; display: flex; flex-direction: column; justify-content: center; padding: var(--s7) var(--s3) var(--s5); }
  .chapter--boss.is-pinned .boss__pin > .chapter__grid { width: 100%; }  /* auto margins inside a flex column shrink the grid and misalign it with the page gutter */
  .chapter--boss.is-pinned .boss__rail { overflow: visible; scroll-snap-type: none; }
  .chapter--boss.is-pinned .boss__track { will-change: transform; padding-left: max(var(--s3), calc((100vw - var(--max-w)) / 2)); }
  .boss__card { width: 300px; }
  .boss__card img { width: 300px; }
}

/* ---------- special dungeon ---------- */
.gate-rules { list-style: none; margin: var(--s4) 0 0; padding: 0; display: grid; gap: var(--s3); max-width: 34em; }
.gate-rules li { position: relative; padding-left: var(--s5); color: var(--paper); }
.gate-rules li::before { content: ""; position: absolute; left: 0; top: .5em; width: 12px; height: 12px; background: var(--light); box-shadow: 0 0 10px var(--light); }
.art-frame--gate { box-shadow: 0 0 0 4px #000, 0 0 0 8px #34304a, 0 0 72px rgba(94, 230, 223, .22); }
.gate-tiers { list-style: none; margin: var(--s6) auto 0; padding: 0; max-width: var(--max-w); display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--s2); }
@media (max-width: 899px) { .gate-tiers { grid-template-columns: repeat(8, 1fr); } .gate-tiers li { grid-column: span 2; } .gate-tiers li:nth-child(5) { grid-column: 2 / span 2; } }   /* 4 + 3, last row centred */
@media (min-width: 900px) { .gate-tiers { grid-template-columns: repeat(7, 1fr); gap: var(--s3); } }
.gate-tiers li { display: grid; justify-items: center; gap: var(--s1); padding: var(--s3) var(--s2); background: linear-gradient(180deg, color-mix(in oklab, var(--face) 55%, #0d0b10), #0d0b10);
  box-shadow: inset 0 0 0 2px #000, inset 0 0 0 4px var(--face), 0 0 24px color-mix(in oklab, var(--glow) 18%, transparent); }
.gate-tiers b { font: 32px/1 var(--font-pixel); font-weight: 400; color: var(--glow); text-shadow: 3px 3px 0 #000; }
.gate-tiers span { font-size: 16px; color: var(--paper); white-space: nowrap; }
.gate-tiers .gate-tiers__days { margin-top: calc(-1 * var(--s1)); font-size: 14px; color: color-mix(in oklab, var(--glow) 70%, var(--paper)); }   /* 28/09: days each gate lasts */
@media (max-width: 374px) { .gate-tiers li { padding-inline: var(--s1); } .gate-tiers span { font-size: 14px; } .gate-tiers .gate-tiers__days { font-size: 13px; } }

/* ---------- rank ---------- */
.rank { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s2); }
.rank__tier { display: grid; grid-template-columns: 80px 1fr; grid-template-areas: "chu lv" "chu nv" "chu mo"; column-gap: var(--s3); padding: var(--s3); background: rgba(0, 0, 0, .35); box-shadow: inset 4px 0 0 var(--tint); }
.rank__letter { grid-area: chu; align-self: center; font: 32px/1 var(--font-pixel); color: var(--tint); text-shadow: 3px 3px 0 #000; }
.rank__level { grid-area: lv; font: 16px/1.4 var(--font-pixel); color: var(--light); }
.rank__quest { grid-area: nv; color: var(--paper); font-size: 17px; line-height: 1.4; }
.rank__unlock { grid-area: mo; color: var(--emerald); font-size: 16px; }
@media (min-width: 900px) {
  .rank__tier { grid-template-columns: 96px 160px 1fr 220px; grid-template-areas: "chu lv nv mo"; align-items: center; }
  .rank__unlock { text-align: right; }
}

/* ---------- rules ---------- */
.rules { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s3); }
@media (min-width: 900px) { .rules { grid-template-columns: repeat(2, 1fr); gap: var(--s4); } }
.rules__card { padding: var(--s4); background: var(--panel); box-shadow: inset 0 0 0 2px #000, inset 0 0 0 4px var(--border), inset 0 4px 0 4px color-mix(in oklab, var(--light) 35%, var(--border)); }
.badge-soon { display: inline-block; vertical-align: middle; margin-left: var(--s3); padding: var(--s1) var(--s2); font: 600 16px/1.2 var(--font-body); color: #06201f; background: var(--soul); text-shadow: none; }
.rules__card p { margin-top: var(--s2); color: var(--muted); font-size: 17px; }

/* ---------- how to play ---------- */
.steps { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s3); }
.steps__item { display: grid; grid-template-columns: 48px 1fr; gap: var(--s3); padding: var(--s4); background: var(--panel); box-shadow: inset 0 0 0 2px #000, inset 0 0 0 4px var(--border); }
.steps__num { width: 48px; height: 48px; display: grid; place-items: center; font: 24px/1 var(--font-pixel); color: #1f1405; background: var(--torch); box-shadow: inset 0 -4px 0 var(--torch-dark); }
.steps__item p { color: var(--muted); margin-top: var(--s1); }
.copy-group { grid-column: 2; }
@media (max-width: 560px) { .copy-group { grid-column: 1 / -1; } }
.copy-field { display: grid; grid-template-columns: 72px 1fr auto; align-items: center; gap: var(--s2) var(--s3); margin-top: var(--s3); padding: var(--s2) var(--s2) var(--s2) var(--s3); background: #0d0b10; box-shadow: inset 0 0 0 2px #000; }
.copy-field__label { color: var(--muted); font-size: 16px; }
.copy-field__value { color: #fff; font-size: 16px; white-space: nowrap; }
@media (max-width: 400px) { .copy-field { grid-template-columns: 1fr auto; grid-template-areas: "label btn" "value value"; padding: var(--s2) var(--s2) var(--s3) var(--s3); }
  .copy-field__label { grid-area: label; } .copy-field .btn { grid-area: btn; } .copy-field__value { grid-area: value; } }
.copy-field + .copy-field { margin-top: var(--s2); }
.chapter--bedrock .chapter__grid { max-width: 800px; }
.quick-join { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s3) var(--s4); }
.quick-join .note { margin: 0; flex: 1 1 260px; }
@media (max-width: 899px) { .quick-join { flex-direction: column; text-align: center; } .quick-join .note { flex: none; } }   /* phones: button and hint centred */
.discord-card { display: grid; grid-template-columns: 72px 1fr; gap: var(--s3) var(--s4); align-items: center; padding: var(--s4); background: #1b1827; box-shadow: inset 0 0 0 2px #000, inset 0 0 0 4px #3d3a63; }
.discord-card img { width: 72px; height: 72px; }
.discord-card p { color: var(--muted); margin-top: var(--s1); }
.discord-card .btn { grid-column: 1 / -1; justify-self: center; }   /* one-column layout: centred under the card text (owner) */
@media (min-width: 900px) { .discord-card { grid-template-columns: 96px 1fr auto; } .discord-card img { width: 96px; height: 96px; } .discord-card .btn { grid-column: auto; } }

.footer { background: var(--bg-bottom); padding: var(--s5) var(--s3) var(--s6); text-align: center; color: var(--muted); font-size: 16px; border-top: 4px solid #000; }
.footer a { color: var(--paper); }
.footer__legal { margin-top: var(--s2); font-size: 14px; }
@media (max-width: 899px) { .footer { padding-bottom: calc(var(--s6) + 48px); } }   /* full-width footer text: keep it clear of the back-to-top button */

/* back to top: pixel arrow, bottom-right, clear of the depth gauge (vertically centred) and the centred toast */
.to-top { position: fixed; right: var(--s3); bottom: var(--s3); z-index: 25; display: grid; place-items: center; width: 48px; height: 48px; padding: 0; border: 0;
  color: var(--paper); background: rgba(10, 8, 12, .8); box-shadow: inset 0 0 0 2px var(--border), 0 4px 0 #000;
  opacity: 0; visibility: hidden; transform: translateY(12px); transition: opacity .2s, transform .2s, visibility 0s .2s, color .15s, box-shadow .15s; }
.to-top.is-visible { opacity: 1; visibility: visible; transform: none; transition: opacity .2s, transform .2s, color .15s, box-shadow .15s; }
.to-top:hover { color: var(--torch); box-shadow: inset 0 0 0 2px var(--torch), 0 4px 0 #000; }
.to-top:active { transform: translateY(2px); box-shadow: inset 0 0 0 2px var(--torch), 0 2px 0 #000; }
.to-top:focus-visible { outline: 2px solid var(--torch); outline-offset: 2px; }
.to-top svg { display: block; image-rendering: pixelated; }
.toast { position: fixed; left: 50%; bottom: var(--s4); z-index: 60; transform: translate(-50%, 24px); opacity: 0; pointer-events: none; padding: var(--s2) var(--s4);
  background: #0d0b10; color: var(--emerald); box-shadow: inset 0 0 0 2px var(--emerald); font-weight: 600; transition: opacity .2s, transform .2s; white-space: nowrap; }
.toast.is-visible { opacity: 1; transform: translate(-50%, 0); }

/* ---------- story beats (scroll-driven, reversible; only under .motion = JS on + motion allowed) ---------- */
.svh-probe { position: fixed; top: 0; left: 0; width: 0; height: 100svh; visibility: hidden; pointer-events: none; }

/* depth gauge marker = the player's head going down */
.depth-gauge__marker { left: 50%; width: 24px; height: 24px; transform: translate(-50%, -50%); background: url(../img/face.png) center / 100% 100% no-repeat;
  image-rendering: pixelated; box-shadow: 0 0 0 2px #000, 0 0 14px var(--light); }

/* gear: tiers light as they reach the feet line; the sword glows in the last reached tier */
.motion .rarity__tier:not(.is-reached) { opacity: .45; }
.motion .rarity__tier { transition: opacity .25s, background .25s, box-shadow .25s; }
.motion .rarity:not(.has-tier) .rarity__pedestal { box-shadow: 0 0 0 4px #000, 0 0 0 8px var(--border); }
.motion .rarity:not(.has-tier) .rarity__sword { filter: grayscale(1) brightness(.7); }
.rarity__pedestal { position: relative; }
.rarity__pedestal.is-upgraded .rarity__sword { animation: level-pop .32s ease-out; }
.rarity__pedestal.is-evolved::after { content: ""; position: absolute; inset: -8px; pointer-events: none; box-shadow: 0 0 0 4px #55ffff; animation: evolve-ring .7s ease-out forwards; }
@keyframes level-pop { 40% { transform: scale(1.14); } }
.rarity__pedestal.is-cursed .rarity__sword { animation: cursed-shake .5s linear; }
@keyframes cursed-shake { 15% { translate: -4px 0; filter: drop-shadow(0 0 12px var(--tint-active)) brightness(.45); } 35% { translate: 4px 0; } 55% { translate: -3px 0; filter: drop-shadow(0 0 12px var(--tint-active)) brightness(.6); } 75% { translate: 2px 0; } }
@keyframes evolve-ring { from { opacity: 1; transform: scale(1); } to { opacity: 0; transform: scale(1.45); } }

/* artifacts: picked up (hop + flash) when they reach the feet line, then bob like a dropped item */
.artifacts__item img { translate: 0 0; }
.motion .artifacts__item.is-picked img { animation: pickup .22s ease-out, bob 2.4s ease-in-out .22s infinite; }
@keyframes pickup { 0% { translate: 0 0; filter: brightness(3); } 45% { translate: 0 -12px; filter: none; } 100% { translate: 0 0; } }
@keyframes bob { 50% { translate: 0 -3px; } }

/* special dungeon: gate plates power up in sequence; the badge stamps once all are lit */
.motion .gate-tiers li { transition: filter .3s, translate .3s; }
.motion .gate-tiers li:not(.is-lit) { filter: brightness(.55) saturate(.6); }
.motion .gate-tiers li.is-lit { translate: 0 -2px; }
.badge-soon.is-stamped { animation: stamp .22s ease-out; }
@keyframes stamp { from { transform: scale(1.5); opacity: .4; } }

/* rules: Vanguard checks every rule card — a scan beam runs down the card, then it is stamped with a check */
.motion .rules__card { position: relative; transition: filter .3s, box-shadow .3s; }
.motion .rules__card h3 { padding-right: 44px; }   /* room for the check badge */
.motion .rules__card:not(.is-verified) { filter: brightness(.6) saturate(.6); }
.motion .rules__card.is-verified { box-shadow: inset 0 0 0 2px #000, inset 0 0 0 4px var(--border), inset 0 4px 0 4px var(--emerald); }
.motion .rules__card::before { content: ""; position: absolute; top: var(--s3); right: var(--s3); width: 32px; height: 32px; opacity: 0;
  background: var(--emerald) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8' shape-rendering='crispEdges'%3E%3Cpath fill='%230b2414' d='M6 1h2v2H7v1H6v1H5v1H4v1H2V6H1V5H0V3h2v1h1v1h1V4h1V3h1z'/%3E%3C/svg%3E") center / 20px 20px no-repeat; box-shadow: 0 0 0 2px #000, 3px 3px 0 2px #000; image-rendering: pixelated; }
.motion .rules__card.is-verified::before { opacity: 1; }
.motion .rules__card.is-scanning::before { animation: stamp .22s ease-out .45s backwards; }
.motion .rules__card.is-scanning::after { content: ""; position: absolute; inset: 0; pointer-events: none; animation: scan .55s linear forwards;
  background: linear-gradient(180deg, transparent 0 42%, rgba(61, 220, 132, .25) 47%, #3ddc84 50%, rgba(61, 220, 132, .25) 53%, transparent 58% 100%) 0 100% / 100% 250% no-repeat; }
@keyframes scan { to { background-position: 0 0; } }

/* special dungeon: a portcullis covers the gate art and winches up as you scroll; the rules light one by one */
.gate-bars { display: none; }
.motion .gate-bars { display: block; position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
.gate-bars__grid { position: absolute; left: 0; right: 0; top: 0; height: 100%; image-rendering: pixelated;
  background: url(../img/blocks/portcullis.png) 0 0 / var(--block) var(--block) repeat;
  transform: translate3d(0, calc(var(--lift, 0) * (-100% - var(--block) / 2)), 0); }
.gate-bars__grid::after { content: ""; position: absolute; left: 0; right: 0; top: 100%; height: calc(var(--block) / 2); image-rendering: pixelated;
  background: url(../img/blocks/portcullis-spikes.png) 0 0 / var(--block) calc(var(--block) / 2) repeat-x; }
.motion .art-frame--gate img { filter: brightness(calc(.4 + .6 * var(--lift, 0))) saturate(calc(.5 + .5 * var(--lift, 0))); }
.art-frame--gate.is-clunk { animation: clunk .32s ease-out; }
@keyframes clunk { 25% { translate: 0 4px; } 55% { translate: 0 -2px; } 80% { translate: 0 1px; } }
.motion .gate-rules li { transition: color .3s; }
.motion .gate-rules li:not(.is-lit) { color: var(--muted); }
.motion .gate-rules li:not(.is-lit)::before { background: #2b3a3c; box-shadow: none; }
.motion .gate-rules li.is-flash::before { animation: bullet-flash .45s ease-out; }
@keyframes bullet-flash { 0% { transform: scale(2); box-shadow: 0 0 24px var(--light); } }

/* rank: sticky Minecraft XP plate; rows light as they reach the feet line */
.rank-wrap { position: relative; }
.xp { display: none; }
.motion .xp { display: block; position: sticky; top: var(--topbar-h, 72px); z-index: 5; margin-bottom: var(--s3); padding: var(--s3) var(--s3) var(--s3);
  background: #0e0c12; box-shadow: inset 0 0 0 2px #000, inset 0 0 0 4px var(--border); }
.xp__row { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s3); margin-bottom: var(--s2); }
.xp__rank { font: 24px/1 var(--font-pixel); color: var(--xp-tint, #aaaaaa); text-shadow: 2px 2px 0 #000; transition: color .2s; }
.xp__level { font: 16px/1 var(--font-pixel); color: var(--muted); }
.xp__level b { font-weight: 400; color: #80ff20; text-shadow: 2px 2px 0 #000; }
.xp__bar { height: 10px; background: #1b1d12; box-shadow: inset 0 0 0 2px #000; position: relative; overflow: hidden;
  background-image: repeating-linear-gradient(90deg, transparent 0 calc(10% - 2px), #000 calc(10% - 2px) 10%); }
.xp__fill { position: absolute; inset: 2px; transform-origin: left; transform: scaleX(var(--xp, 0)); background: linear-gradient(#b6ff5a, #5fcf1f); }
.xp.is-levelup { animation: xp-flash .5s ease-out; }
@keyframes xp-flash { 30% { box-shadow: inset 0 0 0 2px #000, inset 0 0 0 4px #80ff20, 0 0 32px rgba(128, 255, 32, .55); } }
.motion .rank .rank__tier.reveal { transition: opacity .25s, background .25s, transform .6s cubic-bezier(.2, .8, .2, 1); }
.motion .rank .rank__tier.is-visible:not(.is-lit) { opacity: .5; }   /* must outrank .js .reveal.is-visible */
.motion .rank .rank__tier.is-lit { background: color-mix(in oklab, var(--tint) 10%, rgba(0, 0, 0, .35)); }

/* rank-up chat line from the real Vanguard plugin — lives inside the XP plate so it never covers page content */
/* hangs under the plate without taking layout space: toggling it must not move the rank rows (that would re-trigger the SSS threshold) */
.xp__chat { display: none; position: absolute; left: 0; right: 0; top: 100%; padding: var(--s2) var(--s3); background: #0e0c12; box-shadow: inset 0 0 0 2px #000, inset 0 0 0 4px var(--border); font: 16px/1.4 var(--font-pixel); color: #55ff55; text-shadow: 2px 2px 0 #153f15; text-wrap: balance; }
.xp.is-max .xp__chat { display: block; animation: chat-in .25s ease-out; }
/* while the plate is stuck, rows sliding under it hide behind a solid band that then fades (no half-cut row);
   in normal flow (not stuck) there is no band, so the first row is never veiled */
.motion .xp.is-stuck::after, .xp.is-stuck .xp__chat::after { content: ""; position: absolute; left: 0; right: 0; top: 100%; height: 72px; pointer-events: none;
  background: linear-gradient(var(--bg-deep) 0 24px, transparent 72px); }
.motion .xp.is-stuck.is-max::after { display: none; }
@keyframes chat-in { from { opacity: 0; translate: 0 6px; } }
.chat__tag { color: #ffaa00; text-shadow: 2px 2px 0 #3f2a00; }
.chat__rank { color: #ff5555; text-shadow: 1px 0 0 currentColor, 2px 2px 0 #3f1515, 3px 2px 0 #3f1515; }   /* §l bold, drawn the Minecraft way (glyph twice, 1px apart) */

/* bosses: Minecraft boss bar over the pinned corridor; bosses emerge from darkness and dim once passed */
.bossbar { display: none; }
.motion .chapter--boss.is-pinned .bossbar { display: grid; justify-items: center; gap: 14px; width: min(480px, 70%); margin: var(--s5) auto 0; transition: opacity .3s; }
.motion .chapter--boss.is-pinned .bossbar.is-empty { opacity: 0; }
.bossbar__name { font: 16px/1 var(--font-pixel); color: #fff; text-shadow: 2px 2px 0 #3f3f3f; min-height: 16px; white-space: nowrap; }
.bossbar__track { display: block; width: 100%; height: 10px; background: #2a0f16; box-shadow: inset 0 0 0 2px #000; position: relative; }
.bossbar__fill { position: absolute; inset: 2px; transform-origin: left; transform: scaleX(var(--hp, 1)); background: linear-gradient(#ff5d8f, #c0184a); }
.motion .chapter--boss.is-pinned .boss__card img { transition: filter .2s; }
/* a defeated boss is gone (not dimmed). Crossing the arena while scrolling down plays the Minecraft death: red hurt tint, falls over, puff of smoke */
.motion .chapter--boss.is-pinned .boss__card.is-defeated { visibility: hidden; }
.motion .chapter--boss.is-pinned .boss__card.is-dying { visibility: visible; }
.motion .chapter--boss.is-pinned .boss__card.is-dying img { transform-origin: 50% 90%; animation: boss-die .62s ease-in forwards; }
.motion .chapter--boss.is-pinned .boss__card.is-dying span { animation: fade-out .25s forwards; }
@keyframes boss-die {
  0% { filter: brightness(2.2) drop-shadow(0 12px 16px rgba(0, 0, 0, .7)); }
  12%, 70% { filter: sepia(1) saturate(7) hue-rotate(-40deg) brightness(.85); }
  70% { rotate: 90deg; opacity: 1; }
  100% { rotate: 90deg; opacity: 0; filter: sepia(1) saturate(7) hue-rotate(-40deg) brightness(.85); } }
@keyframes fade-out { to { opacity: 0; } }
.boss__poof { position: absolute; z-index: 3; width: 0; height: 0; pointer-events: none; }
.boss__poof i { position: absolute; left: 0; top: 0; width: var(--s); height: var(--s); background: var(--c); animation: puff .8s ease-out forwards; }
@keyframes puff { from { transform: translate(-50%, -50%) scale(.5); opacity: .95; } to { transform: translate(calc(var(--dx) - 50%), calc(var(--dy) - 50%)) scale(1.3); opacity: 0; } }
/* closing card: the corridor ends on "more bosses", never on an empty frame */
.boss__card .boss__more { display: grid; place-items: center; width: 100%; aspect-ratio: 4 / 3; font: 96px/1 var(--font-pixel); color: var(--torch); text-shadow: 4px 4px 0 #000;
  background: radial-gradient(circle at 50% 55%, rgba(255, 178, 56, .16), transparent 60%); box-shadow: inset 0 0 0 2px var(--border); }
.boss__card.boss__card--more { width: auto; min-width: 240px; }   /* grows to fit its one-line caption */
.boss__card--more span:last-child { color: var(--muted); white-space: nowrap; }
@media (min-width: 900px) { .boss__card.boss__card--more { min-width: 300px; } }
.motion .chapter--boss.is-pinned .boss__card.is-focus span { color: #ffd23f; }

/* the first boss starts exactly one card pitch (300 + 24 px) right of the arena (26vw), i.e. at full health; 16px = pin padding */
.motion .chapter--boss.is-pinned .boss__track { padding-left: calc(26vw + 158px); }
/* the reader's claymore holding the arena */
.boss__blade { display: none; }
.motion .chapter--boss.is-pinned .boss__blade { display: block; position: absolute; z-index: 2; width: 144px; height: 144px;
  transform-origin: 25% 80%; rotate: -20deg; filter: drop-shadow(0 0 10px rgba(255, 140, 40, .55)) drop-shadow(0 10px 12px rgba(0, 0, 0, .7)); pointer-events: none; }
.boss__blade.is-slashing { animation: slash .34s ease-out; }
@keyframes slash { 35% { rotate: 70deg; } 100% { rotate: -20deg; } }

/* dungeon wall cover over the dungeon art (canvas drawn by site.js) */
.art-frame__wall { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; image-rendering: pixelated; }

/* bedrock strike: tiny shake of the strip canvas */
.strata__canvas.is-shaking { animation: shake .12s steps(2) 2; }
@keyframes shake { 50% { translate: 0 2px; } }

/* ---------- reveal on scroll ---------- */
.js .reveal { opacity: 0; transform: translateY(24px); transition: opacity .6s ease-out, transform .6s cubic-bezier(.2, .8, .2, 1); }
.js .reveal.is-visible { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .js .reveal { opacity: 1; transform: none; }
}

/* ---------- mouse cursor: the Lightning Rod artifact (16px item texture at 2x = standard 32px cursor, 64px on retina); charged on clickables ---------- */
@media (pointer: fine) {
  html { cursor: url(../img/cursor/rod-32.png) 1 1, auto; cursor: image-set(url(../img/cursor/rod-32.png) 1x, url(../img/cursor/rod-64.png) 2x) 1 1, auto; }
  a, button, [role="button"], label, summary, .rarity__tier {
    cursor: url(../img/cursor/rod-charged-32.png) 1 1, pointer; cursor: image-set(url(../img/cursor/rod-charged-32.png) 1x, url(../img/cursor/rod-charged-64.png) 2x) 1 1, pointer; }
}

/* nothing on the page is selectable (owner's call); no long-press menu on phones, no dragging images */
img, a, button { -webkit-touch-callout: none; }
img { -webkit-user-drag: none; user-drag: none; }
textarea { -webkit-user-select: text; user-select: text; }   /* the hidden textarea the copy button falls back to must stay selectable */
