/* ===========================================================================
   Enchants Unleashed - docs site
   ---------------------------------------------------------------------------
   Palette is derived from the plugin's own subject matter rather than a
   generic dark-SaaS theme: obsidian ground, the violet of the enchantment
   glint, lapis as the support, and forge-ember warmth reserved for the
   Netherite Infusion Anvil and the primary calls to action. The pixel-art
   item icons further down already use amethyst and netherite tones, so the
   page and its artwork now agree instead of fighting.

   Every colour is a token. Recolouring the whole site means editing :root.
   =========================================================================== */

:root {
  color-scheme: dark;

  /* Obsidian ground - warm black with a violet bias, never blue-grey. */
  --void:       #0a0611;
  --void-lift:  #100a1a;
  --surface-1:  #150f20;
  --surface-2:  #1c1429;
  --surface-3:  #241a33;

  /* Enchantment glint - the hero hue. */
  --glint:        #b98bff;
  --glint-bright: #ddc6ff;
  --glint-deep:   #7c4ed9;

  /* Lapis - the support hue, for structure and secondary emphasis. */
  --lapis:      #5f89f2;
  --lapis-deep: #2b4cb8;

  /* Forge ember - scarce by design. Station, primary CTA, nothing else. */
  --ember:        #ff9d4d;
  --ember-bright: #ffc78a;
  --ember-deep:   #c85f1c;

  /* Pushed well past the WCAG AA floor on purpose. AA (4.5:1) is a minimum for
     legibility, not a target for comfort, and light-on-dark body copy sitting
     near the floor reads as washed-out grey. --text-faint was #7e7293, which
     measured 3.99:1 on --surface-2 and actually failed AA outright. Measured on
     --surface-2, the lightest surface any of them sits on:
       --text        16.1:1
       --text-dim    10.7:1   body copy
       --text-faint   6.9:1   captions and small labels */
  --text:       #f4effb;
  --text-dim:   #cfc4e2;
  --text-faint: #a99cc0;

  --line:        rgba(150, 116, 210, .17);
  --line-mid:    rgba(163, 128, 224, .3);
  --line-strong: rgba(185, 139, 255, .5);

  /* Shadows are hue-tinted. Pure black over a violet ground reads as dirt. */
  --shadow-sm: 0 2px 10px -3px rgba(6, 3, 12, .8);
  --shadow-md: 0 16px 36px -18px rgba(10, 4, 22, .95), 0 3px 8px -3px rgba(0, 0, 0, .55);
  --shadow-lg: 0 36px 70px -32px rgba(72, 28, 134, .6), 0 10px 24px -14px rgba(0, 0, 0, .75);
  --glow-glint: 0 0 44px -10px rgba(185, 139, 255, .5);
  --glow-ember: 0 0 44px -10px rgba(255, 157, 77, .45);

  --radius-sm: 8px;
  --radius:    14px;
  --radius-lg: 20px;

  --ease: cubic-bezier(.22, .61, .36, 1);
  --ease-out-back: cubic-bezier(.34, 1.3, .64, 1);

  --shell: min(1160px, calc(100% - 48px));
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }

body {
  margin: 0;
  overflow-x: hidden;
  color: var(--text);
  background: var(--void);
  font: 400 16px/1.7 Inter, system-ui, Arial, sans-serif;
  /* Deliberately NOT -webkit-font-smoothing: antialiased. On a dark ground it
     strips the subpixel weight off light text, so greys render thinner and
     noticeably fainter than their computed contrast implies. */
}

/* Ambient ground. Fixed so it behaves like a backdrop the content moves over,
   rather than a gradient that scrolls away and leaves flat black behind. */
body::before {
  position: fixed;
  z-index: -2;
  inset: 0;
  content: "";
  background:
    radial-gradient(ellipse 62% 44% at 50% -6%, rgba(150, 96, 255, .2), transparent 62%),
    radial-gradient(ellipse 44% 34% at 96% 22%, rgba(70, 108, 226, .14), transparent 68%),
    radial-gradient(ellipse 52% 40% at 4% 68%, rgba(124, 78, 217, .1), transparent 70%),
    var(--void);
}

/* Fine grain. Keeps the large flat fields from banding and gives the shading
   something to sit on. */
body::after {
  position: fixed;
  z-index: -1;
  inset: 0;
  content: "";
  opacity: .5;
  pointer-events: none;
  background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/><feColorMatrix type='saturate' values='0'/></filter><rect width='140' height='140' filter='url(%23n)' opacity='.032'/></svg>");
}

a { color: inherit; }
code {
  color: var(--glint-bright);
  font: 500 .88em/1.6 "JetBrains Mono", "Cascadia Code", ui-monospace, monospace;
}

/* --- scroll progress ------------------------------------------------------ */
.progress {
  position: fixed;
  z-index: 40;
  top: 0;
  left: 0;
  height: 2px;
  width: 100%;
  transform: scaleX(var(--p, 0));
  transform-origin: 0 50%;
  background: linear-gradient(90deg, var(--lapis), var(--glint) 55%, var(--ember));
  box-shadow: 0 0 12px rgba(185, 139, 255, .6);
  pointer-events: none;
}

/* --- nav ------------------------------------------------------------------ */
.nav {
  position: sticky;
  z-index: 30;
  top: 0;
  border-bottom: 1px solid transparent;
  transition: background .3s var(--ease), border-color .3s var(--ease), backdrop-filter .3s;
}
.nav.is-stuck {
  border-bottom-color: var(--line);
  background: rgba(10, 6, 17, .8);
  backdrop-filter: blur(20px) saturate(1.3);
}
.nav-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: var(--shell);
  min-height: 72px;
  margin: auto;
}
.nav-logo, .footer-logo { font-weight: 800; letter-spacing: -.05em; text-decoration: none; }
.nav-logo { display: inline-flex; align-items: center; gap: 10px; font-size: 1.14rem; }
.nav-logo > span:last-child, .footer-logo > span {
  background: linear-gradient(104deg, var(--glint-bright), var(--glint) 45%, var(--lapis));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
/* Holds the logo mark. The padding keeps the glyph off the rounded border --
   without it the crystal's point collides with the corner radius. */
.logo-mark {
  display: block;
  width: 28px;
  height: 28px;
  padding: 3px;
  object-fit: contain;
  border: 1px solid var(--line-strong);
  border-radius: 9px;
  background: linear-gradient(150deg, rgba(185, 139, 255, .22), rgba(95, 137, 242, .1));
  box-shadow: inset 0 0 18px rgba(185, 139, 255, .3), 0 4px 14px -6px rgba(124, 78, 217, .7);
}
.nav-links {
  display: flex;
  align-items: center;
  gap: 4px;
  color: var(--text-dim);
  font-size: .855rem;
  font-weight: 600;
}
.nav-links a {
  position: relative;
  padding: 7px 11px;
  border-radius: var(--radius-sm);
  text-decoration: none;
  transition: color .2s var(--ease);
}
.nav-links a:not(.nav-download)::after {
  position: absolute;
  bottom: 2px;
  left: 11px;
  right: 11px;
  height: 1px;
  content: "";
  transform: scaleX(0);
  transform-origin: 0 50%;
  background: var(--glint);
  transition: transform .28s var(--ease);
}
.nav-links a:hover { color: var(--text); }
.nav-links a:not(.nav-download):hover::after { transform: scaleX(1); }
.nav-download {
  margin-left: 10px;
  padding: 8px 15px !important;
  border: 1px solid var(--line-strong);
  color: var(--glint-bright) !important;
  background: rgba(185, 139, 255, .09);
  transition: background .22s var(--ease), box-shadow .22s var(--ease), transform .22s var(--ease);
}
.nav-download:hover {
  transform: translateY(-1px);
  background: rgba(185, 139, 255, .17);
  box-shadow: var(--glow-glint);
}

main { width: var(--shell); margin: auto; }

/* --- hero ----------------------------------------------------------------- */
.plugin-hero {
  position: relative;
  display: grid;
  place-items: center;
  align-content: center;
  min-height: 660px;
  padding: 92px 0 74px;
  text-align: center;
  /* The runefield below deliberately spreads past the content column. clip (not
     hidden) contains that without creating a scroll container, and without it
     the hero widens the document on narrow viewports. */
  overflow-x: clip;
}

/* Drifting runes. Drawn as SVG rather than set in a font so they cannot
   degrade into tofu on a machine without the glyph coverage. */
.runefield {
  position: absolute;
  z-index: -1;
  inset: -40px -50vw 0;
  overflow: hidden;
  mask-image: radial-gradient(ellipse 60% 70% at 50% 42%, #000 30%, transparent 78%);
  pointer-events: none;
}
.runefield svg {
  position: absolute;
  width: var(--s, 26px);
  height: var(--s, 26px);
  color: var(--glint);
  opacity: 0;
  animation: drift var(--dur, 17s) linear var(--delay, 0s) infinite;
}
@keyframes drift {
  0%   { opacity: 0; transform: translateY(30px) rotate(0deg) scale(.85); }
  12%  { opacity: var(--peak, .5); }
  78%  { opacity: var(--peak, .5); }
  100% { opacity: 0; transform: translateY(-190px) rotate(var(--spin, 22deg)) scale(1.06); }
}

/* Holds the logo itself. The artwork ships with its own rounded tile and
   border, so the placeholder's frame, gradient and inset shading are gone --
   keeping them double-framed the mark. What stays is the cast glow and the
   float, which belong to the page rather than to the artwork. The tilt is
   dropped too: it suited an abstract glyph, but a logo should sit upright. */
.rune {
  position: relative;
  display: grid;
  /* Sized to actually carry the hero rather than sit in it -- the old 116px
     box was scaled for a single letter, which left the real artwork tiny. */
  width: clamp(200px, 26vw, 320px);
  height: clamp(200px, 26vw, 320px);
  place-items: center;
  margin-bottom: 30px;
  /* 28% matches the artwork's own corner radius, measured off the source.
     A percentage rather than a px value so it still lines up at the smaller
     mobile size. The asset is cropped to its frame, so a mismatch here would
     either shave the artwork or leave black slivers against the hero wash. */
  border-radius: 28%;
  box-shadow: 0 24px 80px -26px rgba(124, 78, 217, .85);
  animation: hover-rune 7s ease-in-out infinite;
}
@keyframes hover-rune {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-9px); }
}
/* Halo pulse - the enchanting table's ambient charge. */
.rune::after {
  position: absolute;
  inset: -1px;
  content: "";
  border-radius: inherit;
  box-shadow: 0 0 0 0 rgba(185, 139, 255, .42);
  animation: charge 3.6s ease-out infinite;
  pointer-events: none;
}
@keyframes charge {
  0%   { box-shadow: 0 0 0 0 rgba(185, 139, 255, .42); }
  70%  { box-shadow: 0 0 0 26px rgba(185, 139, 255, 0); }
  100% { box-shadow: 0 0 0 0 rgba(185, 139, 255, 0); }
}
/* Clipped to the same radius as the tile: the artwork's own rounded frame is
   inset inside a square canvas, and without this its near-black corners sit
   as four dark notches over the hero's violet wash. */
.rune img {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: inherit;
}

.eyebrow, .card-kicker, .recipe-title, .command-label {
  margin: 0;
  color: var(--glint);
  font-size: .7rem;
  font-weight: 800;
  letter-spacing: .17em;
}
h1, h2, h3, p { margin-top: 0; }

h1 {
  position: relative;
  margin: 14px 0;
  font-size: clamp(3.6rem, 8.6vw, 6.6rem);
  line-height: .96;
  letter-spacing: -.055em;
}
/* The enchanted-item glint: an iridescent band that sweeps the wordmark on a
   long loop, the way the vanilla enchantment shader sweeps a tool. */
.glint-text {
  background: linear-gradient(
    100deg,
    #fff 0%, var(--glint-bright) 26%, var(--glint) 42%,
    #fff 50%, var(--glint) 58%, var(--lapis) 76%, var(--glint-bright) 100%
  );
  background-size: 260% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: sweep 9s ease-in-out infinite;
}
@keyframes sweep {
  0%, 100% { background-position: 130% 50%; }
  50%      { background-position: -30% 50%; }
}

.hero-copy {
  max-width: 640px;
  margin-bottom: 26px;
  color: var(--text-dim);
  font-size: clamp(1.05rem, 2.1vw, 1.26rem);
}
.plugin-hero-meta { display: flex; flex-wrap: wrap; justify-content: center; gap: 9px; }
.hero-badge {
  padding: 6px 13px;
  border: 1px solid var(--line-mid);
  border-radius: 999px;
  color: var(--glint-bright);
  background: rgba(185, 139, 255, .08);
  font-size: .72rem;
  font-weight: 700;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .06);
}
.hero-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 13px; margin-top: 34px; }

/* --- buttons -------------------------------------------------------------- */
.button {
  position: relative;
  display: inline-flex;
  gap: 10px;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  flex-shrink: 0;
  padding: 13px 22px;
  border-radius: 10px;
  font-size: .89rem;
  font-weight: 750;
  white-space: nowrap;
  text-decoration: none;
  transition: transform .22s var(--ease), box-shadow .22s var(--ease), border-color .22s var(--ease);
}
.button:hover { transform: translateY(-2px); }
.button:active { transform: translateY(0); }
/* Specular sweep on hover. */
.button::before {
  position: absolute;
  top: 0;
  bottom: 0;
  left: -80%;
  width: 55%;
  content: "";
  transform: skewX(-22deg);
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .38), transparent);
  transition: left .55s var(--ease);
}
.button:hover::before { left: 130%; }
.button.primary {
  color: #2a1103;
  /* Ends on #d4691f rather than --ember-deep: the darker stop put the dark
     label at 4.33:1 over the bottom of the button, just under AA. 4.95:1 now,
     same shading direction. */
  background: linear-gradient(118deg, var(--ember-bright), var(--ember) 58%, #d4691f);
  box-shadow: 0 10px 30px -10px rgba(255, 157, 77, .55), inset 0 1px 0 rgba(255, 255, 255, .4);
}
.button.primary:hover { box-shadow: 0 18px 42px -12px rgba(255, 157, 77, .7), inset 0 1px 0 rgba(255, 255, 255, .45); }
.button.secondary {
  border: 1px solid var(--line-mid);
  color: var(--text);
  background: rgba(185, 139, 255, .07);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .05);
}
.button.secondary:hover { border-color: var(--line-strong); box-shadow: var(--glow-glint), inset 0 1px 0 rgba(255, 255, 255, .07); }

/* --- stat band ------------------------------------------------------------ */
.statband {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  margin: 0 0 8px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: linear-gradient(160deg, var(--surface-2), var(--surface-1));
  box-shadow: var(--shadow-lg), inset 0 1px 0 rgba(255, 255, 255, .05);
  overflow: hidden;
}
.statband div { padding: 30px 26px; text-align: center; }
.statband div + div { border-left: 1px solid var(--line); }
.statband b {
  display: block;
  font-size: clamp(2.4rem, 5vw, 3.6rem);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -.05em;
  background: linear-gradient(150deg, #fff, var(--glint) 70%, var(--glint-deep));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.statband span { display: block; margin-top: 9px; color: var(--text-faint); font-size: .74rem; font-weight: 700; letter-spacing: .15em; }

/* --- section scaffolding -------------------------------------------------- */
.section { position: relative; padding: 92px 0; }
.section + .section::before {
  position: absolute;
  top: 0;
  left: 50%;
  width: 100vw;
  height: 1px;
  content: "";
  transform: translateX(-50%);
  background: linear-gradient(90deg, transparent, var(--line-mid) 30%, var(--line-mid) 70%, transparent);
}
.section-heading { max-width: 690px; }
h2 { margin: 10px 0 16px; font-size: clamp(2rem, 4.1vw, 3.3rem); line-height: 1.06; letter-spacing: -.05em; }
h3 { margin-bottom: 10px; font-size: 1.1rem; line-height: 1.25; letter-spacing: -.02em; }
.section-heading > p:last-child, .station-copy > p, .name-styling p { color: var(--text-dim); }
.fine-print { margin: 18px 0 0; color: var(--text-faint); font-size: .87rem; }

/* Grid and flex children default to min-width:auto, so one unbreakable string --
   the MiniMessage tag in the style card, a long placeholder name -- sizes its
   whole track to min-content and pushes the page wider than the viewport.
   Overriding to 0 lets those elements scroll or wrap inside their own box. */
.station > *, .name-styling > *, .builder-inner > *,
.bento > *, .mode-grid > *, .config-grid > *, .styling-stack > *,
.limits-row > *, .rate-row > *, .command-card > * { min-width: 0; }
.code-card code, .command-card code { max-width: 100%; }

/* Shared card shading. Layered: a hairline top highlight for the lit edge, a
   hue-tinted drop shadow for the mass, and a soft inner floor. */
.card-surface {
  border: 1px solid var(--line);
  background: linear-gradient(158deg, var(--surface-2), var(--surface-1) 62%, var(--void-lift));
  box-shadow:
    var(--shadow-md),
    inset 0 1px 0 rgba(255, 255, 255, .055),
    inset 0 -24px 44px -30px rgba(124, 78, 217, .5);
}

/* --- 1. the loop: a timeline, not a row of cards -------------------------- */
.loop {
  position: relative;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 30px;
  margin-top: 46px;
  padding-top: 44px;
}
/* The rail the three steps hang from. */
.loop::before {
  position: absolute;
  top: 15px;
  left: 8%;
  right: 8%;
  height: 1px;
  content: "";
  background: linear-gradient(90deg, transparent, var(--glint-deep) 12%, var(--glint) 50%, var(--glint-deep) 88%, transparent);
}
.loop-step { position: relative; }
.loop-step::before {
  position: absolute;
  top: -36px;
  left: 50%;
  width: 13px;
  height: 13px;
  content: "";
  transform: translateX(-50%) rotate(45deg);
  border: 1px solid var(--glint);
  border-radius: 3px;
  background: var(--void);
  box-shadow: 0 0 0 5px var(--void), 0 0 18px rgba(185, 139, 255, .8);
  transition: background .3s var(--ease), box-shadow .3s var(--ease);
}
.loop-step:hover::before { background: var(--glint); box-shadow: 0 0 0 5px var(--void), 0 0 26px rgba(185, 139, 255, 1); }
.loop-step .step {
  display: block;
  margin-bottom: 12px;
  color: var(--glint-deep);
  font: 700 2.4rem/1 "JetBrains Mono", monospace;
  letter-spacing: -.04em;
}
.loop-step h3 { font-size: 1.22rem; }
.loop-step p { margin: 0; color: var(--text-dim); font-size: .92rem; }

.command-card {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 15px;
  margin-top: 30px;
  padding: 18px 22px;
  border: 1px solid var(--line-mid);
  border-left: 3px solid var(--glint);
  border-radius: var(--radius);
  background: linear-gradient(100deg, rgba(185, 139, 255, .11), rgba(95, 137, 242, .05));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .05);
}
.command-card code { font-size: 1rem; color: var(--text); }
.command-card b { color: var(--ember); }

/* --- 2. modes: a two-up comparison with a seam ---------------------------- */
.mode-grid {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
  margin-top: 40px;
}
.mode-card {
  position: relative;
  min-height: 240px;
  padding: 32px;
  border-radius: var(--radius-lg);
  overflow: hidden;
  transition: transform .3s var(--ease), box-shadow .3s var(--ease), border-color .3s var(--ease);
}
.mode-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg), inset 0 1px 0 rgba(255, 255, 255, .07); }
.mode-card.featured {
  border-color: rgba(255, 157, 77, .32);
  background: linear-gradient(152deg, rgba(255, 157, 77, .12), rgba(200, 95, 28, .05) 55%, var(--surface-1));
}
.mode-card.featured .card-kicker { color: var(--ember); }
.mode-card.featured::after {
  position: absolute;
  top: -30px;
  right: -30px;
  width: 160px;
  height: 160px;
  content: "";
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 157, 77, .2), transparent 68%);
  pointer-events: none;
}
.mode-card h3 { margin-top: 15px; font-size: 1.5rem; }
.mode-card p { margin-bottom: 0; color: var(--text-dim); font-size: .93rem; }

/* --- 3. station: asymmetric, ember-lit ------------------------------------ */
.station {
  display: grid;
  grid-template-columns: 1fr .82fr;
  align-items: center;
  gap: 64px;
}
.recipe-card {
  padding: 32px;
  border-radius: var(--radius-lg);
  border-color: rgba(255, 157, 77, .2);
  background: linear-gradient(158deg, #241726, var(--surface-1) 60%, var(--void-lift));
  box-shadow: var(--shadow-lg), inset 0 1px 0 rgba(255, 255, 255, .06), 0 0 60px -30px rgba(255, 157, 77, .5);
}
.recipe-title { color: var(--ember); }
.recipe-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 9px;
  max-width: 290px;
  margin: 24px auto;
}
/* Inventory slots: square with a bevel, light top-left and dark bottom-right,
   the way Minecraft's own slots are shaded. Warmed slightly to sit inside the
   station's ember lighting instead of reading as cold grey. */
.recipe-grid span {
  display: grid;
  aspect-ratio: 1;
  place-items: center;
  border-radius: 4px;
  background: rgba(10, 6, 15, .8);
  box-shadow:
    inset 2px 2px 0 rgba(196, 170, 210, .2),
    inset -2px -2px 0 rgba(0, 0, 0, .55),
    inset 0 0 0 1px rgba(140, 116, 168, .3);
  transition: transform .25s var(--ease-out-back), box-shadow .25s var(--ease);
}
.recipe-grid span:not(.empty):hover {
  transform: translateY(-3px) scale(1.05);
  box-shadow:
    inset 2px 2px 0 rgba(210, 186, 230, .3),
    inset -2px -2px 0 rgba(0, 0, 0, .5),
    inset 0 0 0 1px var(--line-strong),
    0 10px 22px -8px rgba(124, 78, 217, .8);
}
/* Empty slots stay drawn. A real crafting grid always shows all nine, and
   hiding them turned the recipe into a floating cross. */
/* Item icons. These are not approximations: the two flat item textures are the
   vanilla 16x16 PNGs transcribed pixel-for-pixel into rects, and the anvil is
   the real block model (template_anvil.json) projected the way the inventory
   draws it -- rotate Y 225 then X 30 -- with each visible face's own texture
   window mapped onto its projected parallelogram and vanilla face shading
   (top 1.0, sides 0.8/0.6) baked in. pixelated keeps the texels hard-edged. */
.shard::after, .ingot::after, .anvil-item::after {
  width: 76%;
  height: 76%;
  content: "";
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  image-rendering: pixelated;
}
.shard::after {
  background-image: url("icons/amethyst_shard.svg");
  filter: drop-shadow(0 0 7px rgba(190, 140, 255, .6));
}
.ingot::after {
  background-image: url("icons/netherite_ingot.svg");
  filter: drop-shadow(0 0 6px rgba(255, 157, 77, .28));
}
/* The anvil is a block, so it fills more of its slot than a flat item does,
   exactly as it does in a real crafting grid. */
.anvil-item::after {
  width: 88%;
  height: 88%;
  background-image: url("icons/anvil.svg");
  filter: drop-shadow(0 3px 5px rgba(0, 0, 0, .55));
}
.recipe-key { margin: 0; color: var(--text-faint); font-size: .72rem; text-align: center; }
/* The legend shows the same 16x16 art as the grid, shrunk, so the key and the
   recipe cannot drift apart. */
.key-swatch {
  display: inline-block;
  width: 15px;
  height: 15px;
  margin-left: 8px;
  vertical-align: -3px;
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  image-rendering: pixelated;
}
.shard-key { background-image: url("icons/amethyst_shard.svg"); }
.ingot-key { background-image: url("icons/netherite_ingot.svg"); }
.anvil-key { background-image: url("icons/anvil.svg"); }

/* --- 4. enchantments: a bento, so this section reads as the centrepiece --- */
.bento {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 18px;
  margin-top: 42px;
}
.bento > * {
  padding: 28px;
  border-radius: var(--radius);
  transition: transform .3s var(--ease), box-shadow .3s var(--ease), border-color .3s var(--ease);
}
.bento > *:hover { transform: translateY(-4px); border-color: var(--line-mid); box-shadow: var(--shadow-lg), inset 0 1px 0 rgba(255, 255, 255, .07); }
.bento-lg { grid-column: span 2; }
.bento-md { grid-column: span 3; }
.bento-num {
  display: block;
  margin-bottom: 6px;
  font: 800 3.3rem/1 Inter, sans-serif;
  letter-spacing: -.06em;
  background: linear-gradient(148deg, #fff, var(--glint) 65%, var(--glint-deep));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.bento h3 { margin-bottom: 8px; }
.bento p { margin-bottom: 0; color: var(--text-dim); font-size: .9rem; }
.bento-md .card-kicker { color: var(--lapis); }
.bento-md.papi .card-kicker { color: var(--glint); }
.bento-md h3 { margin-top: 13px; font-size: 1.3rem; }

.builder-card {
  grid-column: span 6;
  border-color: var(--line-mid);
  background: linear-gradient(112deg, rgba(185, 139, 255, .13), rgba(95, 137, 242, .06) 60%, var(--surface-1));
}
.builder-card .command-card { margin-top: 0; background: rgba(10, 6, 17, .45); }
.builder-card h3 { margin-top: 13px; font-size: 1.4rem; }
.builder-inner { display: grid; grid-template-columns: .95fr 1.05fr; align-items: center; gap: 34px; }
/* .bento p is more specific than .fine-print, so restore the fainter tone. */
.bento .fine-print { margin-top: 16px; color: var(--text-faint); font-size: .87rem; }

/* --- 5. limits: tabular data reads as a table, not as cards --------------- */
.limits-table {
  margin-top: 40px;
  border-radius: var(--radius);
  overflow: hidden;
}
.limits-row {
  display: grid;
  grid-template-columns: 190px 1fr;
  align-items: baseline;
  gap: 26px;
  padding: 24px 28px;
  transition: background .25s var(--ease), padding-left .25s var(--ease);
}
.limits-row + .limits-row { border-top: 1px solid var(--line); }
.limits-row:hover { padding-left: 34px; background: rgba(185, 139, 255, .05); }
.limits-row h3 { margin: 0; font-size: 1.5rem; letter-spacing: -.04em; }
.limits-row p { margin: 0; color: var(--text-dim); font-size: .93rem; }
.limits-row.up h3 { color: var(--glint-bright); }
.limits-row.mid h3 { color: var(--lapis); }
.limits-row.off h3 { color: var(--text-faint); }

/* --- 6. books: a distribution, drawn as bars ------------------------------ */
.rates { margin-top: 42px; display: grid; gap: 22px; }
.rate-row { display: grid; grid-template-columns: 210px 1fr 62px; align-items: center; gap: 22px; }
.rate-row strong { font-size: .95rem; font-weight: 650; }
.rate-row small { display: block; margin-top: 3px; color: var(--text-faint); font-size: .8rem; font-weight: 400; }
.rate-track {
  position: relative;
  height: 10px;
  border-radius: 999px;
  background: rgba(10, 6, 17, .8);
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, .8), inset 0 0 0 1px var(--line);
  overflow: hidden;
}
.rate-fill {
  height: 100%;
  width: 0;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--glint-deep), var(--glint));
  box-shadow: 0 0 16px rgba(185, 139, 255, .7);
  transition: width 1.15s var(--ease);
}
.is-visible .rate-fill { width: var(--w); }
.rate-row:nth-child(2) .rate-fill { transition-delay: .1s; }
.rate-row:nth-child(3) .rate-fill { transition-delay: .2s; }
.rate-row:nth-child(4) .rate-fill { transition-delay: .3s; }
.rate-val { color: var(--glint-bright); font: 600 .95rem/1 "JetBrains Mono", monospace; text-align: right; }

/* --- 7. commands ---------------------------------------------------------- */
.config-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; margin-top: 40px; }
.config-card { padding: 26px; border-radius: var(--radius); transition: transform .3s var(--ease), box-shadow .3s var(--ease), border-color .3s var(--ease); }
.config-card:hover { transform: translateY(-4px); border-color: var(--line-mid); box-shadow: var(--shadow-lg), inset 0 1px 0 rgba(255, 255, 255, .07); }
.config-card p { margin-bottom: 0; color: var(--text-dim); font-size: .9rem; }
.config-icon {
  display: inline-block;
  margin-bottom: 18px;
  padding: 4px 10px;
  border: 1px solid var(--line-mid);
  border-radius: 6px;
  color: var(--glint);
  background: rgba(185, 139, 255, .09);
  font: 600 .76rem/1.5 "JetBrains Mono", monospace;
}

/* --- 8. name styling ------------------------------------------------------ */
.name-styling { display: grid; grid-template-columns: 1.05fr .95fr; align-items: center; gap: 56px; }
.code-card {
  padding: 28px;
  border: 1px solid var(--line-mid);
  border-radius: var(--radius);
  background: linear-gradient(140deg, rgba(185, 139, 255, .14), rgba(95, 137, 242, .07));
  box-shadow: var(--shadow-md), inset 0 1px 0 rgba(255, 255, 255, .06);
}
.code-card span { display: block; margin-bottom: 15px; color: var(--glint-bright); font-size: .68rem; font-weight: 800; letter-spacing: .14em; }
.code-card code { display: block; overflow-x: auto; padding-bottom: 4px; color: #fff; font-size: .8rem; white-space: nowrap; }
/* A live sample of what the tag above produces. The stops are the literal hex
   values from the MiniMessage tag, and it deliberately does not animate: this
   is documentation, so it has to show exactly what the tag renders. */
/* Scoped to .code-card so it outranks `.name-styling p`, which would otherwise
   win on specificity and repaint the text opaque, hiding the gradient. */
.code-card .style-demo {
  margin-top: 18px;
  font-size: 1.5rem;
  font-weight: 750;
  letter-spacing: -.02em;
  background: linear-gradient(92deg, #55ddff, #a855f7);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* --- demo captures -------------------------------------------------------- */
/* Both clips were recorded at 2560x1512 and cropped to the GUI rather than
   scaled from the full frame: at page width a whole-frame downscale turns the
   tooltip text to mush, and the tooltips are the entire point of the capture.
   A GIF has no pause, so prefers-reduced-motion is honoured the only way it can
   be -- <source media> hands the browser a still frame and the loop never runs. */
/* Capped at the capture's own 720px: the bento cell is ~1100px wide, and letting
   the GIF stretch to fill it upscales 1.5x and smears the very tooltip text the
   crop was chosen to preserve. Below 720 it scales down, which stays sharp. */
.demo { margin: 0; }
.demo picture { display: block; max-width: 720px; margin-inline: auto; }
.demo img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--void);
}
.demo figcaption {
  max-width: 720px;
  margin: 14px auto 0;
  color: var(--text-faint);
  font-size: .87rem;
  line-height: 1.5;
}
.demo figcaption b { color: var(--text-dim); font-weight: 600; }
.bento .demo { grid-column: span 6; }
/* Keeps .name-styling a two-column grid: the card and the capture share the
   right track instead of the figure wrapping onto a lopsided third cell. */
.styling-stack { display: grid; gap: 22px; }

.pack-note {
  max-width: 840px;
  margin-top: 30px;
  padding: 24px 26px;
  border-radius: var(--radius);
  border-left: 3px solid var(--lapis);
}
.pack-note p { margin: 0; color: var(--text-dim); }
.pack-note .fine-print { margin-top: 12px; }

/* --- 9. install ----------------------------------------------------------- */
.install-panel {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 34px;
  margin: 78px 0 96px;
  padding: 48px 52px;
  border: 1px solid rgba(255, 157, 77, .28);
  border-radius: 24px;
  overflow: hidden;
  background:
    radial-gradient(ellipse 60% 90% at 88% 20%, rgba(255, 157, 77, .17), transparent 62%),
    linear-gradient(132deg, #1d1327, #150e1f 60%, #100a18);
  box-shadow: var(--shadow-lg), 0 0 80px -40px rgba(255, 157, 77, .6), inset 0 1px 0 rgba(255, 255, 255, .06);
}
.install-panel h2 { margin-bottom: 18px; }
.install-panel ol { max-width: 660px; margin: 0; padding-left: 20px; color: var(--text-dim); font-size: .93rem; }
.install-panel li + li { margin-top: 6px; }
.install-panel li::marker { color: var(--ember); font-weight: 700; }

footer { padding: 34px 24px 50px; border-top: 1px solid var(--line); color: var(--text-faint); text-align: center; font-size: .8rem; }
footer p { margin: 5px 0; }
.footer-logo { color: var(--text); }

/* --- scroll reveal -------------------------------------------------------- */
.reveal {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity .7s var(--ease), transform .7s var(--ease);
}
.reveal.is-visible { opacity: 1; transform: none; }
.reveal[data-d="1"] { transition-delay: .08s; }
.reveal[data-d="2"] { transition-delay: .16s; }
.reveal[data-d="3"] { transition-delay: .24s; }
.reveal[data-d="4"] { transition-delay: .32s; }
.reveal[data-d="5"] { transition-delay: .4s; }

/* --- responsive ----------------------------------------------------------- */
@media (max-width: 940px) {
  .bento { grid-template-columns: repeat(2, 1fr); }
  .bento-lg, .bento-md, .builder-card, .bento .demo { grid-column: span 2; }
  .builder-inner { grid-template-columns: 1fr; gap: 24px; }
  .station { grid-template-columns: 1fr; gap: 38px; }
  .config-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 760px) {
  :root { --shell: min(100% - 32px, 1160px); }
  .nav-links { gap: 2px; font-size: .78rem; }
  .nav-links a:not(.nav-download) { display: none; }
  .plugin-hero { min-height: 560px; padding-top: 70px; }
  .rune { width: clamp(170px, 46vw, 224px); height: clamp(170px, 46vw, 224px); }
  .statband { grid-template-columns: 1fr; }
  .statband div + div { border-left: 0; border-top: 1px solid var(--line); }
  .loop { grid-template-columns: 1fr; gap: 34px; padding-top: 0; }
  .loop::before { top: 0; bottom: 0; left: 6px; right: auto; width: 1px; height: auto; background: linear-gradient(180deg, transparent, var(--glint) 12%, var(--glint-deep) 88%, transparent); }
  .loop-step { padding-left: 34px; }
  .loop-step::before { top: 12px; left: 6px; }
  .mode-grid, .config-grid, .name-styling { grid-template-columns: 1fr; }
  .name-styling { gap: 34px; }
  .section { padding: 66px 0; }
  .limits-row { grid-template-columns: 1fr; gap: 8px; }
  .rate-row { grid-template-columns: 1fr 54px; row-gap: 10px; }
  .rate-row .rate-track { grid-column: 1 / -1; order: 3; }
  .install-panel { display: grid; margin: 44px 0 68px; padding: 34px 28px; }
  .install-panel .button { width: 100%; }
}

@media (max-width: 420px) {
  :root { --shell: min(100% - 24px, 1160px); }
  .nav-logo { font-size: 1rem; }
  .bento { grid-template-columns: 1fr; }
  .bento-lg, .bento-md, .builder-card, .bento .demo { grid-column: span 1; }
  .config-grid { grid-template-columns: 1fr; }
  .hero-actions { display: grid; width: 100%; }
  .hero-actions .button { width: 100%; }
  .command-card { align-items: flex-start; flex-direction: column; }
}

/* --- reduced motion ------------------------------------------------------- */
/* Everything above degrades to a static page: no drift, no sweep, no reveal
   transforms, and bars/counters land at their final value immediately. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  .runefield { display: none; }
  .reveal { opacity: 1; transform: none; }
  .glint-text, .style-demo { background-position: 50% 50%; }
}
