Build a single standalone index.html (inline <style>, one inline <script type="module">, no build step, no local assets) for a 404 page called "Vulpa". Exactly one viewport tall (100vh / 100dvh, no scrolling). Shows a 3D fox loaded from a remote GLB whose head and eyes follow the cursor. Reproduce every value exactly.
=== HEAD ===
<html lang="en">, charset utf-8, viewport "width=device-width, initial-scale=1, viewport-fit=cover", <title>404 · Vulpa</title>, theme-color #fbdc80.
Fonts (preconnect https://fonts.gstatic.com + https://fonts.googleapis.com crossorigin): https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700&family=Quicksand:wght@700&display=swap
Import map: "three": "https://unpkg.com/three@0.160.0/build/three.module.js" "three/addons/": "https://unpkg.com/three@0.160.0/examples/jsm/"
=== CSS TOKENS (:root) === --sky-top:#fbd873; --sky-mid:#fce595; --sky-low:#fef1c9; --mist:#fffaf0; --ink:#121212; --ink-soft:#6b6862; --fox:#f28b3a; --fox-deep:#e9741f; --pad:clamp(18px,4.2vw,54px); ,::before,*::after{box-sizing:border-box}. html,body{height:100%;margin:0}. body{font-family:"Manrope",system-ui,sans-serif;color:var(--ink);background:var(--sky-top);overflow:hidden;-webkit-font-smoothing:antialiased}.
=== MARKUP (order) ===
<div class="page"> <div class="sky" aria-hidden="true"> five <span class="cloud cN"> in order c5, c1, c3, c2, c4, then <span class="mist"> </div> <header class="top"> <a class="brand" href="/" aria-label="Vulpa home"> logo SVG + <span>Vulpa</span> </a> <a class="login" href="/login">Log on</a> </header> <main class="stage"> <p class="digits" aria-hidden="true">404</p> <canvas id="fox" role="img" aria-label="A little anxious fox with a map, following your pointer"></canvas> <span class="shadow" aria-hidden="true"></span> <span class="loading" id="loading">Calling the fox…</span> </main> <section class="copy"> <h1>Uh-oh! This map is wrong</h1> <p>We’ll guide you back to a place you know</p> <a class="home" href="/"> chevron SVG + "Take me home" </a> </section> </div>
Logo SVG: viewBox "0 0 40 40", fill currentColor: <circle cx="20" cy="8.4" r="5.4"/> <path d="M4.6 14.2c2.3-.9 4.6.1 5.7 2.4 1.7 3.6 5.3 6 9.7 6s8-2.4 9.7-6c1.1-2.3 3.4-3.3 5.7-2.4 2.4.9 3.4 3.5 2.4 5.9C34.7 28.1 27.9 33 20 33S5.3 28.1 2.2 20.1c-1-2.4 0-5 2.4-5.9Z"/> Chevron SVG: viewBox "0 0 24 24", fill none, stroke currentColor, stroke-width 2.4, round caps/joins, <path d="M15 5l-7 7 7 7"/>.
=== LAYOUT CSS === .page: position relative; height 100vh then 100dvh; flex column; overflow hidden; isolation isolate; background: radial-gradient(120% 70% at 50% 0%, #fbd568 0%, rgba(251,213,104,0) 60%), linear-gradient(180deg, var(--sky-top) 0%, var(--sky-mid) 38%, var(--sky-low) 66%, var(--mist) 90%).
.sky: absolute; inset 0; z-index -1; pointer-events none.
.cloud: absolute; border-radius 50%; filter blur(14px); animation drift 38s ease-in-out infinite alternate; backgrounds: radial-gradient(closest-side, rgba(255,255,255,.95), rgba(255,255,255,0)) 0% 70% / 46% 62% no-repeat, radial-gradient(closest-side, rgba(255,255,255,.9), rgba(255,255,255,0)) 34% 20% / 52% 78% no-repeat, radial-gradient(closest-side, rgba(255,255,255,.95), rgba(255,255,255,0)) 78% 55% / 50% 70% no-repeat, radial-gradient(closest-side, rgba(255,255,255,.8), rgba(255,255,255,0)) 55% 100% / 90% 60% no-repeat .c1 {left:-9%; top:33%; width:30%; height:30%; opacity:.75} .c2 {left:4%; top:49%; width:34%; height:34%; opacity:.9; animation-duration:46s} .c3 {right:-8%; top:22%; width:30%; height:34%; opacity:.85; animation-duration:52s; animation-direction:alternate-reverse} .c4 {right:2%; top:46%; width:36%; height:36%; opacity:.9; animation-duration:42s; animation-direction:alternate-reverse} .c5 {left:8%; top:27%; width:14%; height:12%; opacity:.45} @keyframes drift { from {transform:translateX(-1.5%)} to {transform:translateX(1.5%)} }
.mist: absolute; left -10%; right -10%; bottom -6%; height 56%; background: radial-gradient(60% 70% at 18% 62%, rgba(255,255,255,.95), rgba(255,255,255,0) 70%), radial-gradient(60% 70% at 82% 60%, rgba(255,255,255,.95), rgba(255,255,255,0) 70%), linear-gradient(180deg, rgba(255,250,240,0) 0%, rgba(255,250,240,.85) 45%, var(--mist) 75%)
.top: absolute; inset 0 0 auto 0; z-index 3; flex; align-items center; space-between; padding calc(var(--pad) * .72 + env(safe-area-inset-top)) var(--pad) 0.
.brand: inline-flex; align-items center; gap 9px; color #fff; no underline; font 700 clamp(24px,2.5vw,32px)/1 "Quicksand","Manrope",sans-serif; letter-spacing -.02em; border-radius 10px. svg: 1.22em square, flex none.
.login: inline-flex centred; height clamp(42px,4vw,50px); padding 0 clamp(14px,1.3vw,18px); color #fff; font 600 clamp(15px,1.35vw,17px)/1 "Manrope"; letter-spacing -.01em; border-radius 14px; background linear-gradient(180deg, rgba(255,255,255,.5), rgba(255,255,255,.28)); border 1px solid rgba(255,255,255,.7); box-shadow 0 6px 18px rgba(203,150,32,.22), inset…Build a single standalone index.html (inline <style>, one inline <script type="module">, no build step, no local assets) for a 404 page called "Vulpa". Exactly one viewport tall (100vh / 100dvh, no scrolling). Shows a 3D fox loaded from a remote GLB whose head and eyes follow the cursor. Reproduce every value exactly.
=== HEAD ===
<html lang="en">, charset utf-8, viewport "width=device-width, initial-scale=1, viewport-fit=cover", <title>404 · Vulpa</title>, theme-color #fbdc80.
Fonts (preconnect https://fonts.gstatic.com + https://fonts.googleapis.com crossorigin): https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700&family=Quicksand:wght@700&display=swap
Import map: "three": "https://unpkg.com/three@0.160.0/build/three.module.js" "three/addons/": "https://unpkg.com/three@0.160.0/examples/jsm/"
=== CSS TOKENS (:root) === --sky-top:#fbd873; --sky-mid:#fce595; --sky-low:#fef1c9; --mist:#fffaf0; --ink:#121212; --ink-soft:#6b6862; --fox:#f28b3a; --fox-deep:#e9741f; --pad:clamp(18px,4.2vw,54px); ,::before,*::after{box-sizing:border-box}. html,body{height:100%;margin:0}. body{font-family:"Manrope",system-ui,sans-serif;color:var(--ink);background:var(--sky-top);overflow:hidden;-webkit-font-smoothing:antialiased.
=== MARKUP (order) ===
<div class="page"> <div class="sky" aria-hidden="true"> five <span class="cloud cN"> in order c5, c1, c3, c2, c4, then <span class="mist"> </div> <header class="top"> <a class="brand" href="/" aria-label="Vulpa home"> logo SVG + <span>Vulpa</span> </a> <a class="login" href="/login">Log on</a> </header> <main class="stage"> <p class="digits" aria-hidden="true">404</p> <canvas id="fox" role="img" aria-label="A little anxious fox with a map, following your pointer"></canvas> <span class="shadow" aria-hidden="true"></span> <span class="shadow" aria-hidden="true"></span> <span class="loading" id="loading">Calling the fox…</span> </main> <section class="copy"> <h1>Uh-oh! This map is wrong</h1> <p>We’ll guide you back to a place you know</p> <a class="home" href="/"> chevron SVG + "Take me home" </a> </section> </div>
Logo SVG: viewBox "0 0 40 40", fill currentColor: <circle cx="20" cy="8.4" r="5.4"/> <path d="M4.6 14.2c2.3-.9 4.6.1 5.7 2.4 1.7 3.6 5.3 6 9.7 6s8-2.4 9.7-6c1.1-2.3 3.4-3.3 5.7-2.4 2.4.9 3.4 3.5 2.4 5.9C34.7 28.1 27.9 33 20 33S5.3 28.1 2.2 20.1c-1-2.4 0-5 2.4-5.9Z"/> Chevron SVG: viewBox "0 0 24 24", fill none, stroke currentColor, stroke-width 2.4, round caps/joins, <path d="M15 5l-7 7 7 7"/>.
=== LAYOUT CSS === .page: position relative; height 100vh then 100dvh; flex column; overflow hidden; isolation isolate; background: radial-gradient(120% 70% at 50% 0%, #fbd568 0%, rgba(251,213,104,0) 60%), linear-gradient(180deg, var(--sky-top) 0%, var(--sky-mid) 38%, var(--sky-low) 66%, var(--mist) 90%).
.sky: absolute; inset 0; z-index -1; pointer-events none.
.cloud: absolute; border-radius 50%; filter blur(14px); animation drift 38s ease-in-out infinite alternate; backgrounds: radial-gradient(closest-side, rgba(255,255,255,.95), rgba(255,255,255,0)) 0% 70% / 46% 62% no-repeat, radial-gradient(closest-side, rgba(255,255,255,.9), rgba(255,255,255,0)) 34% 20% / 52% 78% no-repeat, radial-gradient(closest-side, rgba(255,255,255,.95), rgba(255,255,255,0)) 78% 55% / 50% 70% no-repeat, radial-gradient(closest-side, rgba(255,255,255,.8), rgba(255,255,255,0)) 55% 100% / 90% 60% no-repeat .c1 {left:-9%; top:33%; width:30%; height:30%; opacity:.75} .c2 {left:4%; top:49%; width:34%; height:34%; opacity:.9; animation-duration:46s} .c3 {right:-8%; top:22%; width:30%; height:34%; opacity:.85; animation-duration:52s; animation-direction:alternate-reverse} .c4 {right:2%; top:46%; width:36%; height:36%; opacity:.9; animation-duration:42s; animation-direction:alternate-reverse} .c5 {left:8%; top:27%; width:14%; height:12%; opacity:.45} @keyframes drift { from {transform:translateX(-1.5%)} to {transform:translateX(1.5%)} }
.mist: absolute; left -10%; right -10%; bottom -6%; height 56%; background: radial-gradient(60% 70% at 18% 62%, rgba(255,255,255,.95), rgba(255,255,255,0) 70%), radial-gradient(60% 70% at 82% 60%, rgba(255,255,255,.95), rgba(255,255,255,0) 70%), linear-gradient(180deg, rgba(255,250,240,0) 0%, rgba(255,250,240,.85) 45%, var(--mist) 75%)
.top: absolute; inset 0 0 auto 0; z-index 3; flex; align-items center; space-between; padding calc(var(--pad) * .72 + env(safe-area-inset-top)) var(--pad) 0.
.brand: inline-flex; align-items center; gap 9px; color #fff; no underline; font 700 clamp(24px,2.5vw,32px)/1 "Quicksand","Manrope",sans-serif; letter-spacing -.02em; border-radius 10px. svg: 1.22em square, flex none.
.login: inline-flex centred; height clamp(42px,4vw,50px); padding 0 clamp(14px,1.3vw,18px); color #fff; font 600 clamp(15px,1.35vw,17px)/1 "Manrope"; letter-spacing -.01em; border-radius 14px; background linear-gradient(180deg, rgba(255,255,255,.5), rgba(255,255,255,.28)); border 1px solid rgba(255,255,255,.7);…