Skip to content
LandingPagePrompts
Landing Pagegpt-5.5partial cross-check

Monolith Type

A giant extruded wordmark with a specular sweep and a floor reflection

The exact prompt

A. Build one complete valid index.html for a single-viewport landing page for a type-design studio named MONOLITH. Document title: Monolith Type — Monumental Letterforms. Set lang="en". One file only: plain HTML, inline CSS, and one small inline script. No build step, no framework, no bundler. Google Fonts is the only permitted network request; use it for Inter and Instrument Serif with system fallbacks, and do not load any other URL. No external media: no images, no video, no GIF, no canvas, no WebGL, no Three.js, no Lottie, no icon CDN, no base64 photo blobs. Every visible pixel must be generated from HTML, CSS gradients, SVG primitives, pseudo-elements, and text. Desktop is exactly one frame with no scroll at width >= 901px: html and body height:100%; overflow:hidden; .page height:100dvh; overflow:hidden. Mobile and tablet at width <= 900px may scroll vertically but must never overflow horizontally. Create exactly one h1, and split the word MONOLITH into per-letter spans so each letter can cascade in. The page contains only: header, main hero, and footer with three small stat items. Do NOT build extra sections, cards, pricing, forms, testimonials, case studies, blog links, app screenshots, video controls, dark-mode toggles, cookie banners, or a large footer sitemap. The core visual idea is a giant extruded wordmark with a slow specular sweep across its top face and a blurred vertically-faded floor reflection beneath it.

B. THE BACKDROP. Use pure CSS and SVG only; no canvas. The cinematic field is a procedural stage built from three fixed elements behind the page: .stage-field, .stage-grid, and .stage-noise. .stage-field covers inset:0 with background color #050505 and these layered gradients, back to front: radial-gradient(circle at 50% 118%, rgba(242,242,232,0.16) 0%, rgba(242,242,232,0.075) 14%, rgba(242,242,232,0.025) 31%, transparent 52%); radial-gradient(ellipse at 50% 65%, rgba(138,138,122,0.075) 0%, rgba(82,82,74,0.032) 36%, transparent 68%); linear-gradient(180deg, #050505 0%, #070706 38%, #020202 100%). .stage-field::before is the horizon haze: position absolute; left:50%; top:58%; width:min(86vw, 1280px); height:1px; transform:translateX(-50%); background:linear-gradient(90deg, transparent 0%, rgba(242,242,232,0.10) 18%, rgba(242,242,232,0.32) 50%, rgba(242,242,232,0.10) 82%, transparent 100%); filter:blur(0.5px); opacity:0.75. .stage-field::after is the floor plane: position absolute; left:50%; bottom:-12%; width:min(118vw, 1640px); height:46%; transform:translateX(-50%) perspective(760px) rotateX(66deg); transform-origin:50% 100%; border-radius:50% 50% 0 0; background:radial-gradient(ellipse at 50% 0%, rgba(255,255,245,0.105) 0%, rgba(230,230,215,0.045) 22%, rgba(120,120,108,0.018) 48%, transparent 70%), repeating-linear-gradient(90deg, rgba(255,255,255,0.045) 0 1px, transparent 1px 82px), repeating-linear-gradient(0deg, rgba(255,255,255,0.032) 0 1px, transparent 1px 70px); opacity:0.68; mask-image:linear-gradient(180deg, rgba(0,0,0,0.92) 0%, rgba(0,0,0,0.54) 40%, transparent 100%). .stage-grid covers inset:0; opacity:0.35; background-image: linear-gradient(rgba(255,255,255,0.018) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.018) 1px, transparent 1px); background-size:96px 96px; background-position:center calc(50% + 8px); mask-image:radial-gradient(ellipse at 50% 58%, black 0%, black 36%, transparent 74%). Animate .stage-grid with grid-drift for 28s linear infinite from background-position:center calc(50% + 8px) to calc(50% + 96px) calc(50% + 104px). .stage-noise is an inline SVG filter texture element, not an external image: an absolutely positioned div with opacity:0.12, mix-blend-mode:screen, pointer-events:none, background generated by an inline SVG data URL is not allowed; instead create an inline svg element in the HTML containing feTurbulence baseFrequency 0.72, numOctaves 2, seed 17, stitchTiles stitch, and use a full-viewport rect with filter url(#noise-filter). Its CSS opacity is 0.105 on desktop and 0.075 on mobile. The backdrop frame budget is light: animate only transform and background-position; no blur animation; no layout-affecting properties in loops. The only continuously moving visual effects are grid-drift at 28s, the wordmark specular sweep at 7.2s, the optional floor gleam at 9.6s, and the rAF telemetry counter.

C. THE LAYER STACK, back to front. html and body are #050505 at z-index auto. .backdrop is fixed inset:0 z-index:0 pointer-events:none overflow:hidden. Inside .backdrop: .stage-field z-index:0, .stage-grid z-index:1, .stage-noise svg z-index:2. .page is position:relative z-index:10 min-height:100dvh display:grid grid-template-rows:auto 1fr auto. header.site-header is z-index:30. main.hero is z-index:20. .wordmark-scene is z-index:20. The H1 .monolith-stack is position:relative z-index:3. The extrusion layers inside the H1 sit in ordered z-index values: .extrude[data-depth="12"] z-index:1 through .extrude[data-depth="1"] z-index:12, .top-face z-index:20, .specular-mask z-index:24, .letter spans within .top-face z-index:25. The reflection .reflection is z-index:1 beneath the wordmark but above the floor glow. .floor-glow is z-index:0. .hero-copy is z-index:25. footer.metrics is z-index:30. .mobile-menu-panel, when open, is fixed z-index:80. .grain-vignette is fixed z-index:100 pointer-events:none, but keep its opacity under 0.18 so text contrast remains readable.

D. TOKEN TABLE. Define tokens in :root for the 1440px desktop default. Colors: --bg:#050505; --bg-2:#090908; --text:#f7f4ea; --text-soft:#d8d4c9; --muted:#98958b; --muted-2:#6f6c64; --accent:#f2f2e8; --accent-dim:#b9b6aa; --line:rgba(255,255,245,0.14); --line-strong:rgba(255,255,245,0.28); --line-soft:rgba(255,255,245,0.09); --black:#000000; --metal-1:#fbfaef; --metal-2:#dedacf; --metal-3:#a4a095; --metal-4:#4d4b46; --metal-5:#1d1c1a; --floor:rgba(242,242,232,0.13); --focus:#fff7c2. Type: --font-sans:"Inter", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; --font-serif:"Instrument Serif", Georgia, serif; --logo:16px; --nav:13px; --eyebrow:12px; --copy:16px; --stat:12.5px; --button:13px; --word:clamp(118px, 17.8vw, 258px); --word-track:-0.095em; --letter-depth:1.8px; --word-line:0.78; --small-caps-track:0.16em. Layout: --header-x:42px; --header-y:28px; --header-h:44px; --page-pad-x:42px; --hero-pad-top:22px; --hero-pad-bottom:36px; --hero-gap:26px; --copy-max:610px; --word-wrap-max:1380px; --footer-x:42px; --footer-y:28px; --metrics-gap:34px. Shapes: --radius-pill:999px; --radius-soft:14px; --button-h:40px; --nav-h:38px; --chip-h:30px; --focus-w:2px; --focus-offset:4px. Wordmark: --extrude-count:12; --extrude-x:3.8px; --extrude-y:4.4px; --top-shadow:0 1px 0 rgba(255,255,255,0.42), 0 18px 40px rgba(0,0,0,0.66); --body-shadow:0 34px 80px rgba(0,0,0,0.62); --reflection-y:21px; --reflection-blur:8px; --reflection-opacity:0.28; --reflection-height:0.72; --specular-w:32%; --specular-o:0.42. Motion: --ease-out:cubic-bezier(0.16,1,0.3,1); --ease-metal:cubic-bezier(0.65,0,0.35,1); --enter-dur:1.05s; --soft-dur:1.2s; --letter-dur:0.92s; --sweep-dur:7.2s; --grid-dur:28s; --gleam-dur:9.6s.

E. THE COMPOSITION. First CSS rule must be exactly html, body { background: #050505 !important; color: #f7f4ea; } and the body tag must include style="background:#050505;color:#f7f4ea" to prevent a white flash. Body uses margin:0; min-width:320px; font-family:var(--font-sans); text-rendering:geometricPrecision; -webkit-font-smoothing:antialiased. Page grid: .page { position:relative; z-index:10; min-height:100dvh; display:grid; grid-template-rows:auto minmax(0, 1fr) auto; } Desktop lock at >=901px sets html, body { height:100%; overflow:hidden; } and .page { height:100dvh; overflow:hidden; }. Header build order: create header.site-header with display:flex; align-items:center; justify-content:space-between; height:var(--header-h); padding:var(--header-y) var(--header-x) 0; gap:24px. The brand is an anchor with accessible name MONOLITH home and text MONOLITH, font-size var(--logo), font-weight 650, letter-spacing:0.18em, line-height:1, color:var(--text), text-decoration:none. Before the brand text include a 20px by 20px SVG mark: a vertical stone slab rectangle with x=5 y=2 width=10 height=16 rx=1.5 fill none stroke currentColor stroke-width=1.6 and a diagonal highlight path M8 15 L14 4 opacity 0.55. Header nav contains exactly three links: Work, Foundry, Contact. Each link is a pill built to the UI language below. Header right CTA is an anchor with text Request specimen. Mobile burger appears only at <=900px and is a button with aria-label="Open navigation", aria-expanded toggled, and three 16px bars.

Hero build order: main.hero is display:grid; place-items:center; min-width:0; padding:var(--hero-pad-top) var(--page-pad-x) var(--hero-pad-bottom); overflow:visible. Inside it, .hero-inner is width:100%; max-width:var(--word-wrap-max); display:grid; justify-items:center; align-content:center; gap:var(--hero-gap); transform:translateY(-1.2vh) on desktop. Place a small chip above the wordmark: text VARIABLE TYPE SYSTEMS / 2026, height var(--chip-h), padding 0 13px, border 1px solid var(--line), border-radius var(--radius-pill), font-size var(--eyebrow), letter-spacing var(--small-caps-track), color var(--muted), background rgba(255,255,245,0.035). The H1 is visually the giant word only and contains the accessible text MONOLITH once. Structure: h1.monolith-title aria-label="MONOLITH" with .monolith-stack aria-hidden="true" containing exactly 13 visible stacked copies: 12 extrusion spans with class extrude and data-depth values 12 down to 1, then one .top-face. Every copy spells MONOLITH with exactly eight child spans class letter containing M, O, N, O, L, I, T, H. Do not add another h1 or duplicate readable h1 text outside aria-label. H1 CSS: margin:0; width:100%; max-width:var(--word-wrap-max); font-size:var(--word); line-height:var(--word-line); letter-spacing:var(--word-track); font-weight:900; font-family:var(--font-sans); text-align:center; text-transform:uppercase; white-space:nowrap; user-select:none. .monolith-stack is position:relative; display:block; min-height:0.78em; perspective:900px; transform-style:preserve-3d. Extrude layers are position:absolute; inset:0; display:flex; justify-content:center; color set per depth; transform:translate(calc(var(--depth) * var(--extrude-x)), calc(var(--depth) * var(--extrude-y))); text-shadow:0 1px 0 rgba(255,255,255,0.05); filter:brightness(var(--b)). Set depth colors explicitly from nearest to farthest: depth 1 #c9c5b9, 2 #aaa69b, 3 #8e8a80, 4 #747066, 5 #5d5a52, 6 #484640, 7 #37352f, 8 #292721, 9 #201e19, 10 #181611, 11 #11100d, 12 #0b0a08. .top-face is position:relative; display:flex; justify-content:center; color:transparent; background:linear-gradient(180deg, #fffdf2 0%, #e4e0d4 24%, #9d998d 54%, #4d4a43 100%); -webkit-background-clip:text; background-clip:text; text-shadow:var(--top-shadow). .top-face::after is the dark lower bevel: content:""; position:absolute; left:0; right:0; bottom:-0.05em; height:0.14em; background:linear-gradient(180deg, rgba(255,255,255,0.10), rgba(0,0,0,0.52)); -webkit-background-clip:text; background-clip:text; color:transparent; pointer-events:none. .specular-mask is an absolutely positioned child overlay inset:-0.08em -0.04em 0; pointer-events:none; mix-blend-mode:screen; background:linear-gradient(115deg, transparent 0%, transparent 39%, rgba(255,255,255,0.0) 43%, rgba(255,255,255,var(--specular-o)) 50%, rgba(255,255,255,0.10) 54%, transparent 61%, transparent 100%); transform:translateX(-72%); clip-path:inset(0 0 0 0); -webkit-background-clip:text; background-clip:text; color:transparent; animation:specular-sweep var(--sweep-dur) var(--ease-metal) infinite; animation-delay:1.2s. Because background-clip:text cannot clip an empty overlay in all browsers, duplicate the MONOLITH letters inside .specular-mask with aria-hidden="true" and identical letter spans.

Reflection build order: place .reflection immediately after the H1 in .wordmark-scene. It duplicates the top-face MONOLITH only, aria-hidden="true", font settings identical to h1, transform:translateY(var(--reflection-y)) scaleY(calc(-1 * var(--reflection-height))); transform-origin:50% 0%; filter:blur(var(--reflection-blur)); opacity:var(--reflection-opacity); color:transparent; background:linear-gradient(180deg, rgba(255,255,245,0.28) 0%, rgba(255,255,245,0.12) 28%, rgba(255,255,245,0.035) 58%, transparent 100%); -webkit-background-clip:text; background-clip:text; mask-image:linear-gradient(180deg, rgba(0,0,0,0.58) 0%, rgba(0,0,0,0.26) 36%, transparent 78%); pointer-events:none. Add .floor-glow under it: width:min(82vw, 1120px); height:120px; margin-top:-42px; border-radius:50%; background:radial-gradient(ellipse at center, rgba(242,242,232,0.16) 0%, rgba(242,242,232,0.058) 32%, transparent 72%); filter:blur(18px); animation:floor-gleam var(--gleam-dur) ease-in-out infinite. Hero copy below the scene is exactly: Custom lettering for interfaces that need mass, silence, and impossible polish. It is a p.hero-copy with margin:0; max-width:var(--copy-max); color:var(--muted); font-size:var(--copy); line-height:1.65; text-align:center; letter-spacing:-0.012em. Footer metrics: footer.metrics contains nav-free small facts only, exactly three items in a ul: 01 Variable wordmarks, 02 Optical correction, 03 UI type systems. Footer CSS: padding:0 var(--footer-x) var(--footer-y); display:flex; justify-content:center; align-items:center. The ul is display:flex; gap:var(--metrics-gap); list-style:none; padding:0; margin:0; flex-wrap:wrap; justify-content:center. Each li uses font-size var(--stat), letter-spacing:0.13em, text-transform:uppercase, color:var(--muted-2). The numeric prefix is a span color var(--accent-dim), opacity 0.82, margin-right:8px.

F. THE UI LANGUAGE. All clickable header pills share .pill. CSS: height:var(--nav-h); display:inline-flex; align-items:center; justify-content:center; padding:0 16px; border-radius:var(--radius-pill); border:1px solid rgba(255,255,245,0.12); color:var(--text-soft); text-decoration:none; font-size:var(--nav); font-weight:560; letter-spacing:-0.01em; line-height:1; background:linear-gradient(180deg, rgba(255,255,245,0.055) 0%, rgba(255,255,245,0.018) 100%); box-shadow:inset 0 1px 0 rgba(255,255,255,0.08), 0 12px 34px rgba(0,0,0,0.24); backdrop-filter:blur(12px); -webkit-backdrop-filter:blur(12px); position:relative; overflow:hidden; transition:transform 240ms var(--ease-out), border-color 240ms var(--ease-out), color 240ms var(--ease-out), background 240ms var(--ease-out). .pill::before is a 115deg shine: content:""; position:absolute; inset:-1px; background:linear-gradient(115deg, transparent 0%, transparent 34%, rgba(255,255,255,0.16) 50%, transparent 66%, transparent 100%); transform:translateX(-130%); transition:transform 620ms var(--ease-out); pointer-events:none. .pill:hover transforms translateY(-1px), border-color rgba(255,255,245,0.30), color var(--text), background linear-gradient(180deg, rgba(255,255,245,0.095) 0%, rgba(255,255,245,0.032) 100%). .pill:hover::before transform:translateX(130%). .pill:active transform:translateY(0). The CTA .pill--primary uses border-color rgba(242,242,232,0.32), color #11110f, background linear-gradient(180deg, #fbfaef 0%, #d8d4c8 100%), box-shadow inset 0 1px 0 rgba(255,255,255,0.72), 0 16px 46px rgba(242,242,232,0.16); hover background linear-gradient(180deg, #ffffff 0%, #e6e2d6 100%). Focus: every a and button has :focus-visible outline var(--focus-w) solid var(--focus); outline-offset:var(--focus-offset); border-radius:var(--radius-pill). The chip uses the same material but never appears clickable. The mobile menu panel uses a dark glass sheet: background rgba(5,5,5,0.88); backdrop-filter blur(22px); border-top 1px solid var(--line); links height 56px, font-size 22px, letter-spacing -0.03em.

G. MOTION. Resting opacity is always 1 on .appear elements; animations define from states only, and the page remains readable if animation fails. Apply .appear plus a modifier to each animated element. Stagger table: brand mark and word .appear--scale delay 0.06s; nav Work .appear--soft delay 0.14s; nav Foundry .appear--soft delay 0.20s; nav Contact .appear--soft delay 0.26s; header CTA .appear--scale delay 0.32s; chip .appear--pop delay 0.24s; extrusion group .appear--depth delay 0.30s; top-face letter M in-letter delay 0.44s; O delay 0.49s; N delay 0.54s; second O delay 0.59s; L delay 0.64s; I delay 0.69s; T delay 0.74s; H delay 0.79s; specular sweep begins delay 1.20s; reflection .appear--reflect delay 0.88s; hero copy .appear--soft delay 1.02s; metric 01 .appear--stat delay 1.10s; metric 02 delay 1.22s; metric 03 delay 1.34s. Keyframes: in-scale from opacity:0 transform:scale(0.88) to opacity:1 transform:none. in-soft from opacity:0 transform:translateY(14px) filter:blur(5px) to opacity:1 transform:none filter:blur(0). in-pop from 0% opacity:0 transform:scale(0.92), 68% opacity:1 transform:scale(1.035), 100% opacity:1 transform:scale(1). in-depth from opacity:0 transform:translateY(22px) rotateX(12deg) scale(0.985) to opacity:1 transform:none. in-letter from opacity:0 transform:translateY(0.42em) rotateX(72deg) scaleY(0.82); transform-origin:50% 100%; to opacity:1 transform:none. in-reflect from opacity:0 transform:translateY(calc(var(--reflection-y) + 22px)) scaleY(calc(-1 * var(--reflection-height))) to opacity:var(--reflection-opacity) transform:translateY(var(--reflection-y)) scaleY(calc(-1 * var(--reflection-height))). in-stat from opacity:0 transform:translateY(16px) to opacity:1 transform:none. specular-sweep keeps opacity 1 and animates transform from translateX(-76%) to translateX(76%) at 56%, then holds translateX(76%) until 100% so the shine pauses after each pass. grid-drift moves the grid by exactly 96px on both axes. floor-gleam animates opacity 0.52 at 0%, 0.78 at 50%, 0.52 at 100% and scaleX 0.96 to 1.04 to 0.96. Each animation uses animation-fill-mode:both and animation-timing-function:var(--ease-out). On animationend for each .appear element, add .is-in and set inline animation none only for that target through a class rule: .appear.is-in { opacity:1; transform:none; filter:none; clip-path:none; animation:none; }.

H. RESPONSIVE TABLE. Defaults above are for 1440x900. For width >= 1600px set --header-x:56px; --header-y:34px; --logo:17px; --nav:14px; --nav-h:40px; --button:14px; --word:clamp(150px, 17.6vw, 316px); --copy:17px; --copy-max:660px; --word-wrap-max:1660px; --hero-gap:30px; --footer-x:56px; --footer-y:32px; --metrics-gap:42px; --extrude-x:4.4px; --extrude-y:5.0px; --reflection-blur:10px. For width >= 1920px set --header-x:72px; --header-y:38px; --logo:18px; --nav:14.5px; --nav-h:42px; --word:clamp(176px, 17.2vw, 360px); --copy:18px; --copy-max:710px; --word-wrap-max:1840px; --hero-gap:34px; --footer-y:36px; --metrics-gap:52px; --extrude-x:4.8px; --extrude-y:5.4px; --reflection-y:24px; --reflection-blur:11px. For 1280px to 1599px set --header-x:42px; --word:clamp(112px, 17.4vw, 238px); --copy-max:590px; --hero-gap:24px; --extrude-x:3.6px; --extrude-y:4.2px. For 901px to 1279px set --header-x:30px; --header-y:22px; --page-pad-x:30px; --footer-x:30px; --footer-y:22px; --nav:12.5px; --nav-h:36px; --button:12.5px; --logo:15px; --word:clamp(86px, 16.4vw, 188px); --copy:15px; --copy-max:540px; --hero-gap:20px; --metrics-gap:24px; --extrude-x:2.9px; --extrude-y:3.5px; --reflection-y:16px; --reflection-blur:7px. For desktop max-height <= 850px and width >= 901px set --header-y:20px; --hero-pad-bottom:22px; --hero-gap:18px; --word:clamp(82px, 15.8vw, 210px); --copy:14.5px; --footer-y:18px; .hero-inner transform:translateY(-0.4vh). For desktop max-height <= 720px and width >= 901px set --header-y:16px; --header-h:38px; --hero-pad-top:8px; --hero-pad-bottom:14px; --hero-gap:12px; --word:clamp(72px, 14.2vw, 174px); --copy:13.5px; --chip-h:26px; --eyebrow:11px; --footer-y:12px; --stat:11.5px; .reflection opacity:0.20; .floor-glow height:84px. For width <= 900px remove the desktop height lock: html, body { min-height:100%; overflow-x:hidden; } .page { min-height:100dvh; height:auto; overflow:hidden; grid-template-rows:auto minmax(560px, 1fr) auto; } tokens: --header-x:22px; --header-y:20px; --page-pad-x:22px; --footer-x:22px; --footer-y:24px; --header-h:42px; --logo:15px; --word:clamp(54px, 15.5vw, 118px); --word-track:-0.075em; --copy:15px; --copy-max:520px; --hero-pad-top:46px; --hero-pad-bottom:44px; --hero-gap:20px; --metrics-gap:18px; --extrude-x:2.1px; --extrude-y:2.7px; --reflection-y:13px; --reflection-blur:6px; --reflection-opacity:0.22. Hide desktop nav and desktop CTA, show burger. Mobile menu: closed visibility:hidden opacity:0 transform:translateY(-8px); open visibility:visible opacity:1 transform:none; transition 220ms var(--ease-out). For width <= 560px set --header-x:18px; --page-pad-x:18px; --word:clamp(43px, 14.8vw, 78px); --copy:14.5px; --copy-max:340px; --hero-pad-top:54px; --hero-pad-bottom:38px; --hero-gap:18px; --chip-h:28px; --eyebrow:10.5px; --stat:11px; --metrics-gap:13px; --extrude-x:1.35px; --extrude-y:1.8px; --reflection-y:10px; --reflection-blur:4px; .metrics ul flex-direction:column; align-items:center. For width <= 400px set --word:clamp(38px, 14.2vw, 58px); --word-track:-0.062em; --copy-max:310px; --page-pad-x:16px; --header-x:16px; --extrude-x:1.05px; --extrude-y:1.45px. At all widths ensure body, .page, header, main, footer, and .monolith-title use max-width:100%; box-sizing:border-box; and no element exceeds 100vw.

I. FAILURE GUARDS. The .appear class must have opacity:1 as its resting declaration before animation names are applied; animation keyframes handle initial opacity so a failed animation never leaves content invisible. Add .no-motion class only if needed by script after fallback; do not depend on it for readability. JS fallback: after two requestAnimationFrame callbacks, inspect every .appear element with el.getAnimations({ subtree:false }); if none of its animations has playState "running" or "finished", add .is-in to every .appear and add .is-in to every .letter. If an element fires animationend, add .is-in to that element. If the browser lacks getAnimations, run the same .is-in fallback after the two rAFs. prefers-reduced-motion: reduce must set *, *::before, *::after { animation:none !important; transition:none !important; scroll-behavior:auto !important; } and force .appear, .appear.is-in, .letter, .reflection, .specular-mask, .stage-grid, .floor-glow { opacity:1; transform:none; filter:none; clip-path:none; } except .reflection must retain transform:translateY(var(--reflection-y)) scaleY(calc(-1 * var(--reflection-height))) and opacity:var(--reflection-opacity) so it remains visually correct. In reduced motion, hide the moving shine by setting .specular-mask { display:none; }. Maintain contrast: body text color #f7f4ea on #050505 and muted copy #98958b on #050505 exceed 4.5:1 for paragraph-sized text; do not lower opacity on text below 0.86. Add visible focus rings for all controls. Add a window error listener before running animation code and push String(event.message || event.error || "unknown error") to window.__DEMO__.errors. No console.log, console.warn, or console.error in the happy path.

J. THE EXACT JS. Keep the script as a small IIFE at the end of body. It must do only telemetry, animation fallback, and mobile menu behavior. First line inside the script sets window.__DEMO__ = { name: "monolith-type", ready: false, frames: 0, effects: [], errors: [] }; then push implemented effect names exactly once in this order: "css-extruded-wordmark", "specular-sweep", "floor-reflection", "procedural-css-stage", "letter-cascade", "mobile-menu". Add the error listener immediately after creating the object. Start a requestAnimationFrame loop named tick that increments window.__DEMO__.frames once per animation frame; do not perform DOM reads inside the loop. After the first tick has executed and the browser has had one paint opportunity, set window.__DEMO__.ready = true; use requestAnimationFrame(function(){ window.__DEMO__.ready = true; }) from inside the first tick or the immediately following scheduled frame. Cache document.documentElement, the menu button, the mobile panel, and all nav links. Burger behavior: clicking the burger toggles class menu-open on documentElement, updates aria-expanded to "true" or "false", updates aria-label to "Close navigation" or "Open navigation", and sets panel aria-hidden to the inverse. Escape closes the menu. Clicking any link inside the mobile panel closes the menu. Resizing to width > 900 closes the menu. Closing means remove menu-open, button aria-expanded="false", button aria-label="Open navigation", panel aria-hidden="true". Animation behavior: add animationend listeners to every .appear and every .letter; on end add .is-in. Run the two-rAF fallback described above. The script must not create elements, must not fetch, must not use timers, must not write to localStorage, and must not log. Guard every optional element check so missing elements cannot throw.

---

TECHNICAL CONTRACT (non-negotiable):

1. Deliver ONE single file: a complete, valid `index.html`. No build step, no bundler,
   no framework, no package install. It must open correctly by double-clicking the file
   and also over http://.
2. Vanilla only. No React, no Tailwind CDN, no GSAP, no Three.js, no jQuery, no Lottie.
   Plain HTML + CSS + modern JavaScript in <style> and <script> tags.
3. NO external media. No .mp4, no .webm, no .gif, no remote images, no base64 blobs of
   photos. Every visual must be generated procedurally with CSS gradients, SVG, or
   <canvas>. This keeps the page free to host and impossible to break with a dead link.
4. Google Fonts is the ONLY permitted network request, and it must be declared with a
   <link rel="preconnect"> plus a system-font fallback stack so the page still looks
   intentional offline. If you prefer, skip it and use a pure system stack.
5. Responsive and correct at 390x844 (phone), 768x1024 (tablet) and 1440x900 (desktop).
   No horizontal scrollbar at any of those widths. Nothing may overflow its container.
6. Accessibility: exactly one <h1>; real <header>/<main>/<footer>/<nav> landmarks; every
   interactive element is a <button> or <a> with an accessible name; visible :focus-visible
   ring; body text contrast ratio >= 4.5:1 against its background.
7. Motion safety: wrap all continuous motion in
   `@media (prefers-reduced-motion: reduce)` rules that reduce it to a static or
   near-static state. The page must remain fully readable and usable with motion off.
8. Performance: no layout thrash. Cache DOM reads, batch writes inside a single
   requestAnimationFrame loop, use transform/opacity for animation, and never allocate
   inside the hot loop. Target 60fps on a 2019 laptop. Total file under 90 KB.
9. Runtime telemetry hook (used by the automated verifier — implement it exactly):
   at the top of your script define
     window.__DEMO__ = { name: '<slug>', ready: false, frames: 0, effects: [], errors: [] };
   then set `ready = true` after the first paint of your main effect, increment
   `frames` once per animation frame inside your rAF loop, and push the name of each
   implemented effect into `effects`. Add a `window.addEventListener('error', ...)`
   handler that pushes messages into `errors`. Do not rename these fields.
10. Zero console output in the happy path. No console.log left behind. No uncaught
    exceptions, no failed network requests.

RESPONSE FORMAT:
Return ONLY the raw HTML inside a single ```html fenced code block. No explanation, no
preamble, no commentary before or after the fence. The file must be complete and
immediately runnable — never truncate, never write "// rest of code here".

Acceptance criteria (15)

  1. the generated index.html contains exactly one h1, and the h1 exposes aria-label="MONOLITH" while its visual wordmark is split into exactly eight .letter spans per visible word copy
  2. there are exactly 12 extrusion layers plus one top-face layer for the MONOLITH wordmark, and the page contains a .specular-mask with an active specular-sweep CSS animation
  3. window.__DEMO__ exists with name "monolith-type", ready becomes true after first paint, frames increments via requestAnimationFrame, and effects contains css-extruded-wordmark, specular-sweep, floor-reflection, procedural-css-stage, letter-cascade, and mobile-menu
  4. at viewport widths 1440 and 1920, html/body and .page are locked to one 100dvh frame with overflow hidden; at 390px and 768px there is no horizontal overflow
  5. the document performs no network requests except Google Fonts and contains no canvas, video, img, iframe, external media URLs, framework scripts, or third-party CDN assets
  6. window.__DEMO__.ready becomes true within 5s
  7. window.__DEMO__.frames advances (>= 20 frames in 1.2s)
  8. window.__DEMO__.errors is empty
  9. zero console errors and zero page errors
  10. zero failed network requests
  11. exactly one <h1> with non-empty text
  12. header, main, footer landmarks present
  13. no horizontal overflow at 390 / 768 / 1440 widths
  14. no horizontal overflow after 2s of animation
  15. prefers-reduced-motion: reduce leaves the page usable and errors empty

More landing page prompts