diff --git a/packages/app/public/decorative/minecraft/diamond-pickaxe.png b/packages/app/public/decorative/minecraft/diamond-pickaxe.png
new file mode 100644
index 00000000..dae141fa
Binary files /dev/null and b/packages/app/public/decorative/minecraft/diamond-pickaxe.png differ
diff --git a/packages/app/public/decorative/minecraft/diamond.png b/packages/app/public/decorative/minecraft/diamond.png
new file mode 100644
index 00000000..be4fda0d
Binary files /dev/null and b/packages/app/public/decorative/minecraft/diamond.png differ
diff --git a/packages/app/public/decorative/minecraft/ender-dragon.gif b/packages/app/public/decorative/minecraft/ender-dragon.gif
new file mode 100644
index 00000000..11f7f808
Binary files /dev/null and b/packages/app/public/decorative/minecraft/ender-dragon.gif differ
diff --git a/packages/app/public/decorative/minecraft/grass-block.png b/packages/app/public/decorative/minecraft/grass-block.png
new file mode 100644
index 00000000..870cd88b
Binary files /dev/null and b/packages/app/public/decorative/minecraft/grass-block.png differ
diff --git a/packages/app/public/decorative/minecraft/tnt.png b/packages/app/public/decorative/minecraft/tnt.png
new file mode 100644
index 00000000..c4dd2e4e
Binary files /dev/null and b/packages/app/public/decorative/minecraft/tnt.png differ
diff --git a/packages/app/public/decorative/minecraft/zombified-piglin.png b/packages/app/public/decorative/minecraft/zombified-piglin.png
new file mode 100644
index 00000000..9df1c1c5
Binary files /dev/null and b/packages/app/public/decorative/minecraft/zombified-piglin.png differ
diff --git a/packages/app/src/app/globals.css b/packages/app/src/app/globals.css
index 50849070..ee7bc7fb 100644
--- a/packages/app/src/app/globals.css
+++ b/packages/app/src/app/globals.css
@@ -319,6 +319,41 @@
display: none;
}
+/* Ender-dragon fly-across — one-shot animation on minecraft theme activation,
+ * triggered from minecraft-decorations.tsx. Plays once (iteration-count: 1)
+ * and lands the dragon off-screen left so the GIF stops being rendered. */
+@keyframes mc-dragon-flyacross {
+ 0% {
+ transform: translate(110vw, 0) scale(1);
+ opacity: 0;
+ }
+ 8% {
+ opacity: 0.95;
+ }
+ 50% {
+ transform: translate(40vw, -3vh) scale(1.05);
+ }
+ 92% {
+ opacity: 0.95;
+ }
+ 100% {
+ transform: translate(-130vw, 1vh) scale(1);
+ opacity: 0;
+ }
+}
+
+.mc-dragon-flyacross {
+ animation: mc-dragon-flyacross 9s cubic-bezier(0.4, 0, 0.6, 1) 1 forwards;
+ will-change: transform, opacity;
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .mc-dragon-flyacross {
+ animation: none;
+ display: none;
+ }
+}
+
/* Splash text — yellow bouncing rotated text (Minecraft title screen style) */
@keyframes splash-bounce {
0%,
diff --git a/packages/app/src/app/layout.tsx b/packages/app/src/app/layout.tsx
index 22bda276..93088655 100644
--- a/packages/app/src/app/layout.tsx
+++ b/packages/app/src/app/layout.tsx
@@ -11,6 +11,7 @@ import { Footer } from '@/components/footer/footer';
import { Header } from '@/components/header/header';
import { CircuitBackground } from '@/components/circuit-background';
import { MinecraftBackgroundLazy } from '@/components/minecraft/minecraft-background-lazy';
+import { MinecraftDecorations } from '@/components/minecraft/minecraft-decorations';
import { ThemeProvider } from '@/components/ui/theme-provider';
import {
AUTHOR_HANDLE,
@@ -178,6 +179,7 @@ export default async function RootLayout({
+
diff --git a/packages/app/src/components/minecraft/minecraft-decorations.tsx b/packages/app/src/components/minecraft/minecraft-decorations.tsx
new file mode 100644
index 00000000..95aa36ca
--- /dev/null
+++ b/packages/app/src/components/minecraft/minecraft-decorations.tsx
@@ -0,0 +1,164 @@
+'use client';
+
+import { useEffect, useState } from 'react';
+
+/**
+ * Decorative Minecraft asset PNGs scattered around the viewport corners,
+ * plus a one-shot Ender Dragon fly-across at theme activation. Only renders
+ * while the minecraft theme is active. Watches `document.documentElement`
+ * class changes via a MutationObserver so it appears / disappears live with
+ * the mode-toggle (mirrors `minecraft-toggles.tsx`).
+ *
+ * All static images are `pointer-events: none` at low z-index. The dragon is
+ * absolutely positioned and flies right-to-left once per theme activation
+ * (animation-iteration-count: 1) — the GIF's wing-flap plays during the
+ * traversal so the entrance feels alive.
+ *
+ * Asset provenance: minecraft.wiki (CC BY-NC-SA 3.0) for blocks/items/dragon.
+ */
+const DECORATIONS = [
+ // Top-left: Zombified Piglin, mirrored so its sword arm points toward the
+ // middle of the screen rather than off-screen left. Keep the original
+ // -6deg tilt — flipping over X also flips the rotate direction visually,
+ // which lands as a slight forward lean toward the chart area.
+ {
+ src: '/decorative/minecraft/zombified-piglin.png',
+ alt: 'Zombified Piglin',
+ style: {
+ top: '5rem',
+ left: '0.5rem',
+ width: 'min(110px, 9vw)',
+ transform: 'scaleX(-1) rotate(-6deg)',
+ },
+ },
+ // Top-right: Diamond pickaxe, mining vibe.
+ {
+ src: '/decorative/minecraft/diamond-pickaxe.png',
+ alt: 'Diamond pickaxe',
+ style: {
+ top: '5rem',
+ right: '0.5rem',
+ width: 'min(110px, 9vw)',
+ transform: 'rotate(35deg)',
+ },
+ },
+ // Bottom-left: Grass block, classic anchor.
+ {
+ src: '/decorative/minecraft/grass-block.png',
+ alt: 'Grass block',
+ style: {
+ bottom: '4rem',
+ left: '0.5rem',
+ width: 'min(110px, 9vw)',
+ transform: 'rotate(-4deg)',
+ },
+ },
+ // Bottom-mid-left: TNT, ready to go boom.
+ {
+ src: '/decorative/minecraft/tnt.png',
+ alt: 'TNT',
+ style: {
+ bottom: '4rem',
+ left: '20%',
+ width: 'min(95px, 8vw)',
+ transform: 'rotate(6deg)',
+ },
+ },
+ // Bottom-right: Diamond, the loot.
+ {
+ src: '/decorative/minecraft/diamond.png',
+ alt: 'Diamond',
+ style: {
+ bottom: '4rem',
+ right: '0.5rem',
+ width: 'min(95px, 8vw)',
+ transform: 'rotate(-6deg)',
+ },
+ },
+] as const;
+
+export function MinecraftDecorations() {
+ const [active, setActive] = useState(false);
+ // Bumps each time the theme is (re)activated, used as the React key on the
+ // dragon `
` to force-remount and re-trigger the CSS fly-across.
+ const [dragonNonce, setDragonNonce] = useState(0);
+
+ useEffect(() => {
+ let wasMinecraft = document.documentElement.classList.contains('minecraft');
+ setActive(wasMinecraft);
+ if (wasMinecraft) setDragonNonce((n) => n + 1);
+
+ const check = () => {
+ const isMinecraft = document.documentElement.classList.contains('minecraft');
+ setActive(isMinecraft);
+ // Re-trigger the dragon only on a transition off→on, not on every
+ // unrelated class change.
+ if (isMinecraft && !wasMinecraft) setDragonNonce((n) => n + 1);
+ wasMinecraft = isMinecraft;
+ };
+
+ const observer = new MutationObserver(check);
+ observer.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] });
+ return () => observer.disconnect();
+ }, []);
+
+ if (!active) return null;
+
+ return (
+ <>
+
+ {DECORATIONS.map((d) => (
+

+ ))}
+
+
+ {/* One-shot Ender Dragon fly-across. Keyed on dragonNonce so it
+ * remounts (and the CSS animation re-plays) every theme activation. */}
+
+

+
+
+
+ >
+ );
+}