Skip to content
LandingPagePrompts
Landing Pagestealth/space-bunny-alphaverified 18/18partial cross-check

Bracket

A measured editorial landing page whose headings are progressively marked by hand-drawn dashed brackets, corner dots, and one looping red correction.

The exact prompt

A. WHAT IS BEING BUILT

Build a single-file, single-viewport desktop landing page for Marginalia, a research-capture product whose primary action is marking up source material. The page must feel like a clean research document that has acquired four intelligent annotations: a product promise, three workflow headings, a testimonial, and one final call to action. It must not feel like a conventional SaaS hero with a centered headline, floating glass cards, decorative blobs, or a dashboard mock-up.

Create one complete index.html document with lang="en", charset UTF-8, an exact document title of "Marginalia — Keep the useful part", and a responsive viewport declaration of width=device-width, initial-scale=1. The semantic page structure must contain one nav, one header, one main, and one footer. There must be exactly one h1: "Keep the useful part." All other section titles are h2. Every visible control must be a native button or anchor with explicit accessible text. Use a visible 2px focus-visible outline in #C2452D with a 3px offset.

At widths of 901px and above, html, body, and the .page shell must be height: 100dvh; body must use overflow:hidden and the page must fit without vertical scrolling. At widths through 900px, the page may scroll vertically. No horizontal overflow is allowed at any width. The content column is flush-left, its desktop left gutter is exactly 72px, and its desktop text measure is 68ch. Annotation geometry may extend into the right margin but must remain inside the viewport.

Do NOT build a split hero, centered hero, card grid, pricing table, feature icon row, testimonial carousel, dashboard screenshot, map, video, image, photograph, illustration unrelated to annotation, floating blobs, grain image, glassmorphism, neon gradient, dark theme, 3D object, cursor follower, text scramble, parallax, or second looping animation. Do not use external media, remote images, third-party CDNs, base64 assets, framework code, React, Tailwind, GSAP, Three.js, or Lottie. Google Fonts is the only permitted network request. Use IBM Plex Mono at weights 400, 500, and 600; if the font request fails, use ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, and monospace. Load the permitted font stylesheet with preconnect links to fonts.googleapis.com and fonts.gstatic.com. Keep the complete file under 90 KB.

B. THE BACKDROP

The backdrop is a flat #F4F1EA bone field, not a canvas and not a video. Create 5 absolutely positioned ambient layers inside a .backdrop element with pointer-events:none:

1. One 1180px by 820px radial gradient at left:-180px, top:-240px, using rgba(26,24,21,0.035) at 0%, rgba(26,24,21,0.012) at 48%, and transparent at 72%.
2. One 900px by 640px radial gradient at right:-260px, bottom:-300px, using rgba(176,169,158,0.12) at 0% and transparent at 68%.
3. One 1px vertical line at left:71px, top:0, bottom:0, color rgba(26,24,21,0.08).
4. One 1px vertical line at right:71px, top:0, bottom:0, color rgba(26,24,21,0.06).
5. One 26px by 26px repeating-linear-gradient cross-paper texture positioned at right:104px, top:42px, with 1px lines in rgba(26,24,21,0.035), opacity:0.5, and background-size:13px 13px.

The two margin boxes are semantic decorative spans, not controls. Place .margin-note.margin-note--one at left:18px, top:220px, width:24px, height:116px, border:1px dashed rgba(176,169,158,0.7), and opacity:0.06. Place .margin-note.margin-note--two at right:18px, bottom:118px, width:24px, height:84px, the same border, and opacity:0.06. Both are empty, aria-hidden="true", contain no text, and exist visually as quote placeholders.

Every visible annotation is inline SVG with viewBox="0 0 200 95" and preserveAspectRatio="none". The base path is exactly M5 5 L195 5 L195 88 L5 72 Z, fill="none", stroke="#B0A99E", stroke-width="2", vector-effect="non-scaling-stroke", stroke-linecap="round", stroke-linejoin="round", and stroke-dasharray="6 4". Place four corner circles at (5,5), (195,5), (195,88), and (5,72) with r="3.5"; place four midpoint circles at (100,5), (195,46.5), (100,80), and (5,38.5) with r="3"; all eight circles use fill="#B0A99E" and vector-effect="non-scaling-stroke". Wrap the path and circles in a group with transform-origin:50% 50% and transform:rotate(-0.5deg).

Position each annotation overlay as position:absolute around the measured bounds of its target heading. On initial layout and on every ResizeObserver delivery, use the target heading getBoundingClientRect() and the document or shell origin to calculate x,y,width,height. Expand the SVG by 9px horizontally and 17px vertically with the left edge at target.left - 9, top at target.top - 8, width equal to target.width + 18, and height equal to target.height + 16. This single initial/resize measurement is permitted. Never call getBoundingClientRect() inside the rAF loop. The SVG is aria-hidden="true", focusable="false", and pointer-events:none.

Use a transparent SVG line of length 240 from 0,0 to 240,0 as a pathLength source for dash drawing. Animate the visible path from stroke-dashoffset:240 to 0 over 640ms with a custom cubic-bezier(0.16,1,0.3,1). The dots begin after 360ms. Dot scale progresses 0 to 1 in 200ms each with a 40ms stagger, using transform-box:fill-box and transform-origin:center.

The one red correction is a position:absolute 2px-high #C2452D line crossing the word "useful" in the h1. Place it from 4px below the h1’s top to the measured width of the inline text range for "useful" plus 5px. Its transform-origin:left center. Animate scaleX from 0 to 1 over 320ms using cubic-bezier(0.2,0.8,0.2,1), hold for 5.68s, then reset instantly at the end of a 6s cycle. It must be paused under reduced motion and displayed at scaleX:1.

There is no canvas. Therefore there is no canvas resolution trick, device-pixel-ratio handling, pixel buffer, filter, or shadow operation. The rAF work budget is no more than 6 style writes per frame, no more than 2 class toggles, no layout reads, and no allocation of DOM nodes. A frame updates only a cached document timestamp, the global frames counter, and the correction element’s CSS custom property --strike-progress. Pause the loop with document.hidden. Restart it on visibilitychange.

C. THE LAYER STACK

Use this exact front-to-back z-index contract:

1. body and page base: z-index:auto.
2. .backdrop gradients and guide lines: z-index:0.
3. .margin-note placeholders: z-index:1.
4. nav: z-index:5.
5. main: z-index:10.
6. inline heading annotation SVGs: z-index:11.
7. the h1 red correction line: z-index:12.
8. footer: z-index:20.
9. .sr-only utility: z-index:100, but it remains 1px by 1px and visually hidden.

The .page element is position:relative; min-height:100dvh; isolation:isolate. All positioned annotation SVG elements are children of their associated .marked section, not of body. Each .marked section is position:relative and must not create a stacking context. Each annotation overlay’s parent section can receive z-index:11 only if it is also position:relative; the SVG itself must remain z-index:11. Header, main, and footer must never overlap at desktop.

D. TOKEN TABLE

Define every recurring size and color in :root. Do not replace these decisions with inline repeated values:

--bone: #F4F1EA
--ink: #1A1815
--ink-soft: #4A463F
--pencil: #B0A99E
--red-pencil: #C2452D
--paper-line: rgba(26,24,21,0.10)
--paper-rule: rgba(176,169,158,0.34)
--focus: #C2452D
--font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace
--page-gutter: 72px
--content-max: 1120px
--measure: 68ch
--nav-height: 76px
--footer-height: 72px
--header-space: 52px
--hero-space: 68px
--section-gap: 28px
--section-rule: 1px
--annotation-x-inset: 9px
--annotation-y-inset: 8px
--annotation-x-expand: 18px
--annotation-y-expand: 16px
--annotation-stroke: 2px
--annotation-rotation: -0.5deg
--dash-array: 6 4
--dash-length: 240
--draw-duration: 640ms
--dot-duration: 200ms
--dot-stagger: 40ms
--strike-duration: 320ms
--strike-period: 6000ms
--ease-draw: cubic-bezier(0.16,1,0.3,1)
--ease-strike: cubic-bezier(0.2,0.8,0.2,1)
--radius-pill: 999px
--radius-card: 2px
--button-height: 44px
--button-padding-x: 20px
--focus-ring: 2px
--focus-offset: 3px
--desktop-line: 0.72
--small-line: 0.82
--body-size: 15px
--small-size: 11px
--micro-size: 10px
--nav-size: 12px
--hero-size: clamp(56px,5.2vw,92px)
--h2-size: clamp(24px,2.2vw,34px)
--testimonial-size: clamp(20px,1.8vw,27px)

E. THE COMPOSITION

The nav uses height:var(--nav-height), padding:0 var(--page-gutter), display:grid, grid-template-columns:1fr auto 1fr, align-items:center. The left link contains the wordmark "MARGINALIA / 01". The center navigation contains two links, "How it works" and "Field notes". The right action is an anchor button with exact copy "Start marking". On widths through 760px, the center navigation is display:none; the grid remains 1fr auto and the right action remains visible.

The header sits directly below nav with padding:52px 72px 0. Its left edge matches the main column. Place a 10px uppercase eyebrow with exact copy "RESEARCH CAPTURE / BETA". Under it, place the only h1 with exact copy "Keep the useful part." The h1 uses font-size:var(--hero-size), line-height:0.96, font-weight:500, letter-spacing:-0.055em, max-width:68ch, and color:var(--ink). The phrase "useful" must be wrapped in span#useful-word. Beneath the h1, place a 2-column grid with grid-template-columns:minmax(0,68ch) 180px, column-gap:48px, align-items:end. The left paragraph exact copy is "Marginalia turns research into a marked-up record. Capture the line, add the reason, and return later to the thought that changed your work." The right meta block uses exact copy "NO / LOGIN REQUIRED" and "BUILT FOR / CLOSE READING". The paragraph is font-size:15px, line-height:1.7, max-width:68ch.

Main contains a workflow region with padding:52px 72px 0. Its top rule is 1px solid var(--paper-rule). Use a 3-row single-column grid, gap:20px, and each row is min-height:82px. Each marked row contains a numbered mono label and an h2. Exact row copy is:

01 / CAPTURE
"Mark the sentence, not the screen."

02 / INTERRUPT
"Add the objection while it is sharp."

03 / RETURN
"Leave a trail your future self can follow."

Only every third heading is wrapped by an SVG overlay. Therefore annotate row 03 only: the heading "Leave a trail your future self can follow." gets the standard bracket overlay. Rows 01 and 02 remain unmarked, creating a deliberate cadence rather than making every heading decorative.

The main also contains a 2-column evidence band with margin-top:38px, padding-top:22px, border-top:1px solid var(--paper-rule), and grid-template-columns:minmax(0,1.7fr) minmax(220px,0.8fr), gap:54px. The left block is a blockquote with exact copy: “The best notes are not transcripts. They are arguments with the source.” The attribution below is "ANIKA SEN / INDEPENDENT RESEARCHER". The right block uses exact copy "01 SOURCE / 02 REASON / 03 CONSEQUENCE" with 13px line-height:1.75 and color var(--ink-soft). This is text, not a card.

The footer uses height:72px, padding:0 72px, display:grid, grid-template-columns:1fr auto 1fr, align-items:center, border-top:1px solid var(--paper-rule). Left copy is "MARGINALIA / RESEARCH TOOL". Center link exact copy is "hello@marginalia.work". Right copy is "© 2025 / BETA 01". The center and right items are right-aligned. The footer is real and visible; it is not a fixed overlay.

F. THE UI LANGUAGE

Primary button and all action links use height:44px, min-width:132px, padding:0 20px, border:1px solid var(--ink), border-radius:999px, background:linear-gradient(135deg, #1A1815 0%, #1A1815 72%, #302C27 100%), color:#F4F1EA, font:500 12px/1 var(--font-mono), letter-spacing:0.02em, display:inline-flex, align-items:center, justify-content:center, gap:10px, cursor:pointer, transition:transform 180ms var(--ease-draw), background 180ms ease, color 180ms ease. Add a 6px by 6px red-pencil dot using a pseudo-element. On hover, transform:translateY(-2px), background:linear-gradient(135deg, #C2452D 0%, #A93825 100%), and the dot changes to #F4F1EA. On active, transform:translateY(0) scale(0.98). On focus-visible, outline:2px solid var(--focus), outline-offset:3px.

Secondary text links have no button fill, no underline, and color:var(--ink). Their hover state changes color to var(--red-pencil). Focus-visible receives the same ring. The nav center links use 12px uppercase mono text with 24px gap. Do not add hover animation to body text or headings.

G. MOTION

Use CSS custom-property delays on annotation SVGs. The stroke keyframes are bracket-draw: from stroke-dashoffset:240 to 0 over 640ms. The dot keyframes are bracket-dot: 0% opacity:0; transform:scale(0); 100% opacity:1; transform:scale(1). The correction keyframes are correction-strike: 0% transform:scaleX(0); 5.33% transform:scaleX(1); 100% transform:scaleX(1), with animation-duration:6000ms. At animation iteration boundary, the next iteration begins at 0. The red line is the only looping animation.

Stagger table:

- header eyebrow: fade-up, 0ms delay, 420ms.
- h1: fade-up, 80ms delay, 620ms.
- hero paragraph and meta: fade-up, 180ms delay, 520ms.
- workflow row 01: fade-up, 240ms delay, 460ms.
- workflow row 02: fade-up, 300ms delay, 460ms.
- workflow row 03 text: fade-up, 360ms delay, 460ms.
- workflow row 03 annotation path: bracket-draw, IntersectionObserver activation, 640ms.
- workflow row 03 corner dot 1: bracket-dot, activation +360ms, 200ms.
- workflow row 03 corner dot 2: bracket-dot, activation +400ms, 200ms.
- workflow row 03 corner dot 3: bracket-dot, activation +440ms, 200ms.
- workflow row 03 corner dot 4: bracket-dot, activation +480ms, 200ms.
- workflow row 03 midpoint dot 1: bracket-dot, activation +520ms, 200ms.
- workflow row 03 midpoint dot 2: bracket-dot, activation +560ms, 200ms.
- workflow row 03 midpoint dot 3: bracket-dot, activation +600ms, 200ms.
- workflow row 03 midpoint dot 4: bracket-dot, activation +640ms, 200ms.
- evidence block: fade-up, 520ms delay, 520ms.
- footer: fade-in, 620ms delay, 420ms.

Use opacity and transform only for non-SVG text motion. Define .reveal with opacity:0, transform:translateY(14px), and .reveal.is-visible with opacity:1, transform:translateY(0). The final resting state of all text is opacity:1, not opacity:0. Do not animate SVG x, y, width, or height in rAF.

IntersectionObserver uses threshold:0.2 and rootMargin:"0px 0px 0px 0px". It adds .is-visible to .reveal elements and .is-drawn to annotation SVG elements. An annotation is drawn once. Disconnect each observed element after activation. If IntersectionObserver is unavailable, add the active classes synchronously after first paint.

H. RESPONSIVE TABLE

Desktop, minimum width:901px: --page-gutter:72px; --nav-height:76px; --footer-height:72px; --header-space:52px; --hero-space:68px; --section-gap:28px; body overflow:hidden; html, body, .page height:100dvh; nav, header, main, footer use the 72px horizontal gutter; content max-width:1120px; the workflow has 3 rows; annotation overlays remain 18px wider and 16px taller than their target.

Tablet, 901px through 1199px: --page-gutter:48px; --nav-height:68px; --footer-height:64px; --header-space:38px; --hero-space:48px; --hero-size:clamp(52px,6.4vw,72px); body overflow:hidden; nav, header, main, footer use 48px gutters; evidence gap:36px; annotation rotation remains -0.5deg.

Small, 601px through 900px: --page-gutter:32px; --nav-height:64px; --footer-height:auto; --header-space:32px; --hero-space:40px; --section-gap:24px; body overflow-y:auto; .page min-height:100dvh and height:auto; nav, header, main, footer use 32px gutters; header’s 2-column hero grid becomes one column; evidence band becomes one column with gap:24px; workflow rows use min-height:96px; margin notes remain in viewport edges at 12px.

Phone, 390px through 600px: --page-gutter:20px; --nav-height:60px; --footer-height:auto; --header-space:24px; --hero-space:34px; --hero-size:clamp(42px,12vw,58px); --h2-size:25px; --body-size:14px; --small-size:10px; body overflow-y:auto; nav padding:0 20px; nav center links display:none; header, main, footer padding-left:20px and padding-right:20px; nav wordmark is 10px; primary button is 40px high and min-width:112px; hero meta moves below the paragraph with 16px gap; workflow grid uses 1fr; row number occupies 72px; row h2 max-width:calc(100vw - 112px); evidence block uses 1fr; footer uses 1fr auto and places copyright on a second line; .margin-note--one is 7px from the left, and .margin-note--two is 7px from the right.

Short-height breakpoint, max-height:760px and min-width:901px: --header-space:28px; --hero-space:28px; --section-gap:14px; --nav-height:64px; --footer-height:56px; workflow row min-height:58px; evidence margin-top:20px; footer line remains 1px.

Short-height mobile breakpoint, max-height:700px and max-width:900px: --header-space:20px; --hero-space:26px; --section-gap:16px; workflow row min-height:76px; evidence margin-top:22px. These two max-height rules must not disable scroll.

At every breakpoint, clamp annotation SVG widths to calc(100vw - 32px) on small screens and keep its left coordinate at or above 8px. Never allow the annotation SVG to create horizontal scroll.

I. FAILURE GUARDS

All content has a resting opacity of 1. If JavaScript does not run, remove the .js class from html and the reveal selectors must default to visible; initialize reveal styles only after the first successful script setup. All annotation paths begin fully drawn only if their class is never added? No: the visual resting state must be readable, so SVG path default stroke-dashoffset:0 and dot default opacity:1. When JavaScript is active and the annotation has not been observed, add .is-armed, which sets stroke-dashoffset:240 and dot opacity:0 with transform:scale(0). On activation, .is-drawn restores the final state. The red correction default is visible at scaleX:1 and only becomes animated after the two-rAF fallback has completed.

Use a two-rAF fallback before animation: requestAnimationFrame(() => requestAnimationFrame(() => { document.documentElement.classList.add("motion-ready"); syncAllAnnotations(); setReady(); })). If the second frame does not execute within 1200ms, a setTimeout fallback marks all reveal elements visible, marks all annotations drawn, marks motion-ready, and sets ready:true. This fallback is cleared after either path completes.

Under prefers-reduced-motion:reduce, html, body, and every component must be static and readable. Disable reveal transforms, SVG stroke drawing, dot scaling, and the correction loop. Set .reveal to opacity:1 and transform:none; set annotation path stroke-dashoffset:0; set every dot opacity:1 and transform:scale(1); set the correction to scaleX(1). Do not start the rAF loop. Mark all annotation overlays visible immediately and set ready:true after first paint.

J. THE EXACT JS

Use one inline script after the closing footer. Create this exact telemetry object first:

window.__DEMO__ = { name: 'bracket', ready: false, frames: 0, effects: [], errors: [] };

Register window error and unhandledrejection listeners. Each error handler pushes the string form of event.reason or event.message into window.__DEMO__.errors, without console output. Register a resize listener only when ResizeObserver is unavailable; otherwise observe every .marked and the .page shell. Cache all elements once in arrays: reveals, annotations, annotationPaths, annotationDots, strike, and strikeWord. Cache document.documentElement and document.body references.

Define measureAnnotation(annotation) with these operations: read annotation.dataset.target, resolve that target, read target.getBoundingClientRect(), read page.getBoundingClientRect() once, compute left as target.left - page.left - 9, top as target.top - page.top - 8, width as target.width + 18, height as target.height + 16, clamp left to 8 and width to the page clientWidth minus left minus 8, then assign annotation.style.transform and annotation.style.width and annotation.style.height. Set the SVG viewBox, preserveAspectRatio, path, and circles in the HTML; JS only positions the overlay. The path must use pathLength="240" and style stroke-dasharray:6 4, stroke-dashoffset:240 when armed.

Define syncStrike once: read usefulWord.getBoundingClientRect(), read h1.getBoundingClientRect(), cache strikeLeft, strikeTop, and strikeWidth, then set strike.style.transformOrigin="left center". The first measurement is outside rAF and is repeated only on resize and ResizeObserver delivery. The rAF loop never reads layout.

The rAF callback is function frame(now) { if (document.hidden) { rafId = 0; return; } window.__DEMO__.frames += 1; const phase = ((now - startedAt) % 6000) / 6000; const progress = phase < 0.0533333333 ? phase / 0.0533333333 : 1; strike.style.setProperty("--strike-progress", String(progress)); rafId = requestAnimationFrame(frame); }. It writes only the cached strike custom property and increments telemetry. Do not toggle classes or measure anything in this callback. Start it only after motion-ready and only when !prefersReduce. On visibilitychange, cancel the current rAF when hidden and restart it with a fresh startedAt when visible. Push each initialized effect name exactly once into effects as "box-draw", "corner-dots", and "red-correction".

After first paint, set ready:true, begin the rAF loop, and disconnect the 1200ms fallback. All event handlers use passive listeners where applicable. The script must contain no console calls, no throw statements, no async dependencies, and no external module imports.

---

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. At 1440x900, the document has one nav, one header, one main, one footer, exactly one h1, and no horizontal or vertical page overflow; at 390x844 it has no horizontal overflow and body vertical scrolling is enabled.
  2. The page contains one visible Marginalia navigation, the exact h1 text “Keep the useful part.”, the four workflow rows, the exact evidence quote, and the exact footer copy; every visible button or link has a non-empty accessible name.
  3. The workflow contains one annotation SVG with viewBox="0 0 200 95", preserveAspectRatio="none", path data beginning M5 5 L195 5 L195 88 L5 72 Z, stroke-dasharray 6 4, eight annotation circles, and a group rotation of -0.5deg.
  4. window.__DEMO__ exists with name "bracket", ready becomes true after first paint, frames increases during a 1.2 second desktop run, effects includes box-draw, corner-dots, and red-correction, and errors remains empty during normal interaction.
  5. With prefers-reduced-motion:reduce, reveal text, annotation strokes, dots, and the red correction are visible and static, the rAF loop does not run, and the page remains readable at 390x844, 768x1024, 1440x900, and 1920x1080.
  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