Landing Pagestealth/space-bunny-alphaverified 18/18unparsed cross-check
Cant
A signal-red freight field where clipped-corner geometry, canted tonnage bars, and a left-to-right loading scan turn operational data into one industrial motion system.
The exact prompt
A. WHAT IS BEING BUILT
Build one complete, framework-free landing page for Ferrolane, a freight forwarder operating rail and short-sea legs across Northern Europe. The page is a single-screen desktop logistics manifesto and route-manifest viewer, not a scrolling marketing site. Use semantic HTML, plain CSS, and plain JavaScript in one index.html. Set the document title to “Ferrolane — Northern Europe, on the cant” and set the document language to en. The visual thesis is “the cant”: one 14px diagonal chamfer appears on the top-right and bottom-left corners of every rectangular surface, turning a standard logistics interface into a forward-leaning industrial system.
The HTML viewport rule is width=device-width, initial-scale=1. The root is 100dvh. At 901px width and wider, html and body must be exactly 100dvh with overflow:hidden; the main region must fit without internal scrolling. At 900px width and below, the document may scroll vertically, but it must never scroll horizontally. Support 390x844, 768x1024, 1440x900, and 1920x1080. Use one Google Fonts request only, loading Archivo at weights 500, 600, and 700, with the fallback stack Arial, Helvetica, sans-serif. If the font request fails or is blocked, the page must remain correct.
Do NOT build a video, animated GIF, image element, remote asset, base64 asset, SVG illustration, WebGL scene, 3D chart, map, globe, loader screen, cookie panel, authentication form, dashboard sidebar, multi-page navigation, modal, carousel, horizontal scroller, parallax image, stock photograph, or second primary CTA. Do NOT use React, Tailwind, GSAP, Three.js, Lottie, a framework, bundler, build step, icon CDN, analytics service, or any network request other than Google Fonts. Do NOT add border-radius. Do not add box-shadow, text-shadow, drop-shadow, gradients inside text, or decorative pills. Do not use opacity below 0.72 for required text. Do not use JavaScript layout reads, getBoundingClientRect, getComputedStyle, scroll listeners, interval timers, or Web Animations API. Do not make manifest rows keyboard controls unless they perform a real navigation. Do not include more than one h1.
B. THE BACKDROP
The entire viewport is one flat #E03127 signal-red field. There is one body pseudo-element backdrop. It uses a fixed linear gradient from #E03127 at 0% to #E03127 at 100%; the identical stops prevent an unintended visual gradient. Its size is 100% 100%, its position is fixed at inset:0, its z-index is 0, and it has pointer-events:none. Add one fixed 2px vertical near-black registration line at x=48px from top to bottom using a body::after pseudo-element with opacity:0.18. Do not add a second decorative background layer.
Create 126 bar elements in one chart field: 9 visual columns multiplied by 14 vertical positions. Each bar is an empty div with class “tonnage-bar”. The chart uses CSS Grid with 9 equal columns and 14 equal rows. The 126 heights are not random and are not derived at runtime from viewport dimensions. Hard-set every bar using the exact 14-row value array below, repeated in the listed order for each of 9 columns:
Column 1: 34, 46, 58, 42, 66, 52, 74, 61, 78, 69, 83, 72, 88, 76.
Column 2: 38, 50, 62, 47, 71, 56, 79, 66, 84, 73, 87, 76, 91, 81.
Column 3: 42, 55, 65, 51, 74, 60, 82, 70, 87, 77, 90, 80, 94, 84.
Column 4: 46, 59, 68, 55, 77, 64, 85, 73, 89, 80, 92, 83, 96, 87.
Column 5: 50, 63, 71, 59, 80, 68, 88, 77, 91, 83, 95, 86, 98, 90.
Column 6: 54, 66, 74, 63, 82, 72, 90, 80, 93, 86, 97, 89, 100, 93.
Column 7: 58, 70, 77, 67, 85, 76, 93, 84, 95, 89, 99, 92, 100, 96.
Column 8: 62, 73, 80, 71, 87, 79, 95, 87, 97, 92, 100, 95, 100, 98.
Column 9: 66, 77, 84, 75, 90, 83, 98, 91, 99, 95, 100, 98, 100, 100.
Render each value as a percentage height inside a fixed chart cell. The bars use #E03127 as their own fill against the same red field and are separated only by 1px rgba(0,0,0,0.18) inset strokes. Their base cell has the global cut polygon. Each bar is rotated 8deg around its bottom center and skewed -6deg on the X axis, preserving the leaning direction of the cut. The chart occupies the lower two-thirds and extends 72px beyond the right viewport edge; clip the chart wrapper, not the page.
Canvas count is zero. Therefore there is no canvas element, no canvas resolution trick, no getContext call, no ctx.filter, no ctx.shadowBlur, and no per-item canvas compositing. The 126 bars must be transformed by the compositor. A representative 1440x900 performance budget is no more than 1.42 milliseconds of scripting per animation frame, no more than 3.2 milliseconds of style recalculation per frame during the 3.8-second entrance sequence, and no layout-triggering property changes. The post-entrance rAF loop performs only a numeric counter increment and an effect array lookup. Transform and opacity are the only animated CSS properties.
Use three decorative data rules behind the foreground copy. One rule extends from x=0 to 100%, sits at y=67%, and is 1px rgba(0,0,0,0.18). One rule sits at x=48px and spans 38% of viewport height. One rule sits at x=calc(50vw + 12px) and spans 64% of viewport height. Their drift periods are 0 seconds because they remain static. The only continuous background movement is a 7.4-second opacity drift on a 180px soft radial highlight centered at 78% 28%, ranging from opacity:0.035 to opacity:0.07; the highlight never changes position and never resembles a second subject.
C. THE LAYER STACK
Use this back-to-front z-index stack exactly:
z-index:0: body and the fixed flat red backdrop.
z-index:1: the two vertical registration rules and one horizontal data rule in .atmosphere.
z-index:2: .header, the clipped 64px navigation bar.
z-index:3: .manifest, the clipped 3-column route table.
z-index:4: .hero, including eyebrow, h1, deck, CTA, service status, and 9x14 bar field.
z-index:5: the one-time 90-degree white clip sweep.
z-index:6: .footer and its clipped 1px footer rule.
z-index:10: the focus-visible outline layer, created by native :focus-visible with position:relative and z-index:10; never remove it.
The header, manifest, hero, and footer are siblings inside a positioned .stage. The bar field is contained by .chart-window with overflow:hidden. Do not rely on source order to create overlap: set every listed z-index explicitly.
D. TOKEN TABLE
Define these exact custom properties on :root and consume them rather than introducing undocumented sizes:
--red: #E03127;
--ink: #0E0E0E;
--white: #FFFFFF;
--cool: #B9C4CB;
--rule: rgba(0,0,0,0.18);
--paper-line: rgba(255,255,255,0.64);
--field-x: 48px;
--field-y-top: 32px;
--grid-gap: 24px;
--grid-columns: repeat(12,minmax(0,1fr));
--cut: 14px;
--cut-path: polygon(0 0,calc(100% - 14px) 0,100% 14px,100% 100%,14px 100%,0 calc(100% - 14px));
--stroke: 1px;
--header-h: 64px;
--footer-h: 44px;
--type-display: clamp(54px,6.2vw,118px);
--type-title: 17px;
--type-body: 14px;
--type-label: 11px;
--type-data: 12px;
--line-tight: 0.88;
--line-title: 1.15;
--line-body: 1.35;
--weight-medium: 500;
--weight-bold: 700;
--letter-label: 0.12em;
--letter-display: -0.055em;
--ease-cant: cubic-bezier(.2,.8,.2,1);
--duration-bars: 520ms;
--duration-sweep: 900ms;
--duration-row: 140ms;
--bar-stagger: 26ms;
--bar-rotation: 8deg;
--bar-shear: -6deg;
--chart-bleed: 72px;
--focus-ring: #FFFFFF;
--focus-offset: 4px;
--status-green: #FFFFFF;
--reduced-duration: 1ms.
All values in the implementation must come from these tokens or from a declared component rule. Do not use a token for border-radius because every computed border-radius must be 0.
E. THE COMPOSITION
The body uses padding:0. The .stage is position:relative; width:100%; height:100dvh; min-height:680px; overflow:hidden; background:#E03127; color:#0E0E0E; font-family:Archivo,Arial,Helvetica,sans-serif.
The header is a semantic nav inside header.header. It is 64px high and starts at top:0 with left:0; width:100%. It has 48px left padding, 48px right padding, border-bottom:var(--stroke) solid var(--rule), and the exact --cut-path. Inside it, use a 12-column grid with 24px gutters. The brand occupies columns 1 through 3, the route statement columns 5 through 9, and the contact link columns 11 through 12. The brand text is “FERROLANE” in 17px, 700 weight, line-height:1, letter-spacing:-0.025em. The route statement is “RAIL / SHORT SEA / NORTHERN EUROPE” in 11px, 600 weight, letter-spacing:0.12em. The contact link is “ROUTE DESK ↗” in 12px, 700 weight and is right aligned. All three are real visible text; the contact link is an anchor with href="mailto:routes@ferrolane.example" and accessible name “Email the Ferrolane route desk”. The nav has aria-label="Primary navigation”.
The main element is .hero and is positioned absolute with top:96px; left:48px; right:48px; bottom:76px. Use a 12-column grid with 24px gutters, grid-template-rows:112px 1fr 92px, and align-items:start. Place .eyebrow at grid-column:1 / 5; grid-row:1. Place the h1 at grid-column:1 / 10; grid-row:2; align-self:start. Place .hero-copy at grid-column:1 / 5; grid-row:3. Place .chart-window at grid-column:5 / 13; grid-row:2 / 4; margin-top:22px; margin-right:-72px. Place .manifest at grid-column:10 / 13; grid-row:1 / 3; align-self:start; margin-top:20px.
The eyebrow exact copy is “WEEK 29 / NORTH SEA CORRIDOR”. It is 11px, 700 weight, line-height:1, letter-spacing:0.12em, and includes a 32px white horizontal line after the text. Use a 7px square, not a circle, as the status marker. The h1 exact copy is “MOVE HEAVY. / KEEP LEANING.” It uses var(--type-display), weight 700, line-height:0.88, letter-spacing:-0.055em, and max-width:980px. It is the only h1. The hero copy exact copy is “Scheduled rail and short-sea capacity from Malmö to the North Sea ports. One operating window. 11,840 tonnes committed.” It is 14px, weight 500, line-height:1.35, max-width:360px. The CTA is an anchor with href="mailto:routes@ferrolane.example?subject=Capacity%20request" and exact copy “REQUEST CAPACITY ↗”. It is the page’s only inverted white CTA and has an accessible name “Request Ferrolane capacity”. A small status block below it reads “NEXT DEPARTURE / 04 SEP / 06:40” in 11px, 600 weight, letter-spacing:0.12em.
The .chart-window is 100% width, 100% height, position:relative, overflow:hidden, and has the exact --cut-path. It has a 1px solid rgba(0,0,0,0.18) stroke through an inset box-shadow? Shadows are forbidden, so use border:var(--stroke) solid var(--rule) and then apply the cut. Inside, .bars is a 9-column by 14-row grid with 1px gaps, width:100%, height:100%, padding:18px, transform-origin:bottom left. Each .bar-cell is a div with position:relative; min-width:0; min-height:0; overflow:hidden; border:var(--stroke) solid var(--rule); and the exact --cut-path. Each .tonnage-bar is position:absolute; inset:auto 0 0; width:100%; height:var(--bar-height); background:#E03127; border-top:var(--stroke) solid rgba(255,255,255,0.64); transform-origin:bottom center; transform:rotate(8deg) skewX(-6deg) scaleY(0). Do not use shadows.
The .manifest is a real section with aria-labelledby="manifest-title". It has a 1px border, the exact cut path, background:transparent, and padding:18px 18px 16px. Its heading is “LIVE MANIFEST” in 11px, 700 weight, letter-spacing:0.12em, and is not an h2 because the document has one h1; use a p with id="manifest-title". The three exact route rows are “MALMÖ → HELSINGBORG”, “GOTHENBURG → OSLO”, and “AARHUS → ESBJERG”. Each row is a 3-column CSS grid: 1fr 74px 58px, 13px row gap, and 16px vertical padding. The route name is 12px, 700 weight. The departure is 11px in --cool. The load is 12px, 700 weight, right aligned. The exact data strings are “04 SEP / 06:40” with “84%”; “05 SEP / 11:15” with “72%”; and “06 SEP / 07:05” with “91%”. Add a 1px rule between rows. The final footer line in the manifest reads “UPDATED 04:12 UTC” in 10px, 600 weight, letter-spacing:0.08em.
The footer is a semantic footer fixed at bottom:0; left:0; right:0; height:44px. It uses --cut-path, border-top:var(--stroke) solid var(--rule), 48px horizontal padding, and a 12-column grid. The left copy in columns 1 through 5 is “FERROLANE FREIGHT FORWARDING / 55.6050° N, 12.9940° E”. The right copy in columns 10 through 12 is “NORTH SEA / 2025”. Use 10px, 600 weight, letter-spacing:0.1em. The page must contain no text that overflows the 12-column grid at 1440px or 1920px.
F. THE UI LANGUAGE
Every rectangular surface with a visible boundary uses the exact --cut-path. This includes header, manifest, chart window, CTA, footer, bar cells, and the footer rule container. Every border-radius declaration is 0. No box-shadow or text-shadow is allowed anywhere. Separation is limited to 1px rgba(0,0,0,0.18) borders and 1px rgba(255,255,255,0.64) bar top rules.
The CTA is a solid #FFFFFF block with #0E0E0E type, no border, 152px minimum width and 42px height, padding:0 18px, display:inline-flex, align-items:center, justify-content:space-between, font-size:12px, font-weight:700, letter-spacing:0.08em, and the exact cut path. Its default background is #FFFFFF. Its hover background is #B9C4CB. Its hover transform is translate(2px,-2px). Its active transform is translate(0,0). The navigation and manifest hover states do not use color inversion; they use a red inset block sliding from left to right, because the CTA is the one inverted control.
Every visible anchor and button must have a visible :focus-visible ring using outline:3px solid var(--focus-ring); outline-offset:var(--focus-offset); border-radius:0. The focus ring is not clipped by an ancestor with overflow:hidden; if a parent must clip visuals, reserve 8px around focusable content. The manifest rows are not links or buttons, so they must not receive a false control treatment.
G. MOTION
Entrance motion is CSS-only for the visual elements. JavaScript only creates the hard-set bar heights and starts the reveal class. The bar sequence uses the following stagger table:
.eyebrow: opacity 0 to 1 and translateY(10px) to translateY(0), duration 420ms, ease var(--ease-cant), delay 80ms.
h1: opacity 0 to 1 and translateY(18px) to translateY(0), duration 620ms, ease var(--ease-cant), delay 140ms.
.hero-copy: opacity 0 to 1 and translateX(-12px) to translateX(0), duration 480ms, ease var(--ease-cant), delay 260ms.
CTA: opacity 0 to 1 and translateY(8px) to translateY(0), duration 420ms, ease var(--ease-cant), delay 360ms.
.manifest: opacity 0 to 1 and translateX(16px) to translateX(0), duration 520ms, ease var(--ease-cant), delay 240ms.
Bar 1: scaleY(0) to scaleY(1), duration 520ms, ease var(--ease-cant), delay 0ms.
Each subsequent bar adds 26ms. Bar 126 therefore begins at 3,250ms and completes at 3,770ms.
.clip-sweep: translateX(-120%) rotate(90deg) to translateX(120%) rotate(90deg), duration 900ms, ease cubic-bezier(.2,.8,.2,1), delay 500ms, iteration-count 1.
Manifest row hover: a ::before block starts at translateX(-100%) opacity:0.18 and ends at translateX(0) opacity:0.18 over 140ms with ease-out.
Name the keyframes exactly “cantBarsGrow”, “cantCopyIn”, “cantSweep”, “cantRowIn”, and “cantDrift”. The .reveal class applies cantCopyIn to non-bars and cantBarsGrow to bars. The sweep has pointer-events:none and is clipped to the stage. The bar transforms must remain composited; never animate width, height, top, left, margin, padding, filter, clip-path, or background-position. The row highlight uses transform and opacity only.
H. THE RESPONSIVE TABLE
At 1440x900, use the desktop tokens exactly: --field-x:48px; --field-y-top:32px; --header-h:64px; --footer-h:44px; --type-display:96px; --type-title:17px; --type-body:14px; --grid-gap:24px. Keep the hero top at 96px, bottom at 76px, and 12 columns. The h1 uses 96px maximum, the chart bleeds 72px, and the manifest is 318px wide.
At 1920x1080, override --field-x:64px; --field-y-top:40px; --header-h:72px; --footer-h:48px; --type-display:118px; --grid-gap:32px. Use top:112px; bottom:80px; left:64px; right:64px. The chart margin-right is 96px and the manifest is 360px wide. The grid remains 12 columns, 32px gutters, and zero optical centring.
At 768x1024, switch the page to scrollable document flow. Override --field-x:28px; --field-y-top:20px; --header-h:60px; --footer-h:42px; --type-display:64px; --type-body:13px; --grid-gap:18px. Set body overflow-x:hidden and body overflow-y:auto. Set .stage min-height:1280px and height:auto. Set .header position:relative. Set .hero position:relative; inset:auto; display:grid; grid-template-columns:repeat(8,minmax(0,1fr)); grid-template-rows:auto auto auto 420px; row-gap:24px; margin:0 28px. Put eyebrow in columns 1 / 7, h1 in columns 1 / 9, copy in columns 1 / 5, CTA in columns 1 / 5, and chart-window in columns 2 / 9. Put manifest in columns 1 / 9 below the chart, with a fixed height of 246px. Footer remains relative after the main.
At 390x844, override --field-x:18px; --field-y-top:16px; --header-h:58px; --footer-h:40px; --type-display:46px; --type-title:14px; --type-body:12px; --type-label:10px; --grid-gap:12px. Use 4 columns in the header and 4 columns in the hero. The header hides the route statement visually with display:none and retains the brand in columns 1 / 3 and the route desk link in columns 3 / 5. The hero uses row-gap:18px and a minimum height of 1460px. The h1 spans all 4 columns. The copy and CTA span all 4 columns. The chart-window spans all 4 columns, is 390px high, and has margin-right:-18px. The manifest follows the chart, uses padding:14px, and has a height of 270px. Route rows use grid-template-columns:1fr 68px 48px. The footer uses two rows of 20px and does not overlap the chart.
Add a max-height:760px breakpoint. At desktop widths, override --header-h:56px; --footer-h:40px; --type-display:clamp(52px,5.2vw,82px); --type-label:10px; --type-body:12px. Set .hero top:76px; bottom:58px; grid-template-rows:88px 1fr 74px. Reduce chart margin-top to 8px and manifest margin-top to 10px. Do not reduce the bar count.
Add a max-height:640px breakpoint. At desktop widths, override --header-h:52px; --footer-h:36px; --type-display:clamp(44px,4.4vw,68px); --type-label:9px; --type-data:10px. Set .hero top:64px; bottom:48px; grid-template-rows:72px 1fr 62px. Set the hero copy line-height:1.2, CTA height:36px, and chart margin-top:4px. The page remains clipped and readable with no vertical scroll at >=901px.
I. FAILURE GUARDS
The resting state of all readable text, links, manifest content, and footer content must be opacity:1. Add a .js-ready class to body only after DOM construction. The initial CSS state uses opacity:0 only for elements that have an .enter class, and the first rAF adds .reveal. If JavaScript does not run, a 1.8s CSS fallback reveals all non-bar copy and displays a 2-column static tonnage sample. The two-rAF fallback is mandatory: requestAnimationFrame is called once to schedule a first paint, then a second requestAnimationFrame is called before adding .reveal and setting ready=true. Never leave the page permanently invisible if either rAF callback is delayed.
Under prefers-reduced-motion:reduce, set animation-duration:1ms, animation-delay:0ms, transition-duration:1ms, transition-delay:0ms, and transform:none on .enter, .tonnage-bar, .clip-sweep, .manifest-row::before, and .atmosphere-glow. Keep opacity:1 for all readable content. Do not run the visual entrance sequence in reduced-motion mode. The telemetry rAF loop may continue at a low-cost counter cadence of one callback per animation frame, but it must not cause layout or paint. All numeric values, labels, and controls must remain readable.
J. THE EXACT JS
Place this JavaScript at the end of body, before the closing body tag, without modules, imports, external scripts, or a framework. It must execute after the complete DOM exists:
(() => {
"use strict";
const telemetry = window.__DEMO__ = {
name: "cant",
ready: false,
frames: 0,
effects: [],
errors: []
};
window.addEventListener("error", event => {
telemetry.errors.push(String(event.message || "window error"));
});
const columns = [
[34,46,58,42,66,52,74,61,78,69,83,72,88,76],
[38,50,62,47,71,56,79,66,84,73,87,76,91,81],
[42,55,65,51,74,60,82,70,87,77,90,80,94,84],
[46,59,68,55,77,64,85,73,89,80,92,83,96,87],
[50,63,71,59,80,68,88,77,91,83,95,86,98,90],
[54,66,74,63,82,72,90,80,93,86,97,89,100,93],
[58,70,77,67,85,76,93,84,95,89,99,92,100,96],
[62,73,80,71,87,79,95,87,97,92,100,95,100,98],
[66,77,84,75,90,83,98,91,99,95,100,98,100,100]
];
const chart = document.querySelector(".bars");
if (chart) {
const fragment = document.createDocumentFragment();
columns.forEach(column => {
column.forEach(value => {
const cell = document.createElement("div");
cell.className = "bar-cell";
const bar = document.createElement("div");
bar.className = "tonnage-bar enter";
bar.style.setProperty("--bar-height", value + "%");
bar.style.setProperty("--bar-delay", (fragment.childNodes.length * 26) + "ms");
cell.appendChild(bar);
fragment.appendChild(cell);
});
});
chart.appendChild(fragment);
}
const effects = ["bar-grow", "clip-sweep", "row-highlight"];
effects.forEach(effect => telemetry.effects.push(effect));
const reduced = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
const stage = document.querySelector(".stage");
const body = document.body;
const first = window.requestAnimationFrame(() => {
window.requestAnimationFrame(() => {
body.classList.add("js-ready");
if (stage) stage.classList.add(reduced ? "is-static" : "is-active");
telemetry.ready = true;
});
});
function frame() {
telemetry.frames += 1;
window.requestAnimationFrame(frame);
}
window.requestAnimationFrame(frame);
})();
The JavaScript must not write telemetry repeatedly to the DOM, create a timer, inspect geometry, or alter the bar array. The only dynamic style writes are the 126 CSS custom properties --bar-height and --bar-delay assigned while constructing bars. Keep the effect names exactly “bar-grow”, “clip-sweep”, and “row-highlight”.
---
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)
- A headless browser at 1440x900 reports document.body.scrollWidth equal to document.documentElement.clientWidth, document.documentElement.scrollHeight equal to 900, and window.__DEMO__.name equal to "cant" with ready true after two animation frames.
- A headless browser counts exactly one h1, one header, one main, one nav, one footer, 126 .tonnage-bar elements, and zero img, video, canvas, iframe, or external script elements.
- At 1440x900, every visible rectangular component using the cut treatment has computed border-radius equal to "0px", no computed box-shadow, and a clip-path beginning with the specified 14px chamfer polygon.
- The CTA has an accessible name, the route-desk link has an accessible name, both anchors are keyboard focusable with a visible :focus-visible outline, and the reduced-motion media query leaves the h1, CTA, manifest, and footer readable with computed opacity 1.
- The performance check observes at least 20 telemetry.frames increments during a 1.2 second headless interval at 1440x900, with window.__DEMO__.errors.length equal to 0 and no getBoundingClientRect or getComputedStyle calls in the source.
- window.__DEMO__.ready becomes true within 5s
- window.__DEMO__.frames advances (>= 20 frames in 1.2s)
- window.__DEMO__.errors is empty
- zero console errors and zero page errors
- zero failed network requests
- exactly one <h1> with non-empty text
- header, main, footer landmarks present
- no horizontal overflow at 390 / 768 / 1440 widths
- no horizontal overflow after 2s of animation
- prefers-reduced-motion: reduce leaves the page usable and errors empty