diff --git a/packages/web/src/app/page.tsx b/packages/web/src/app/page.tsx index 8469068..7ec4057 100644 --- a/packages/web/src/app/page.tsx +++ b/packages/web/src/app/page.tsx @@ -1,9 +1,11 @@ import type { Metadata } from "next" +import Image from "next/image" import Link from "next/link" import { Button } from "@/components/ui/button" import { Eyebrow, Heading, Lede, Section, Title } from "@/components/ui/section" import { servicesInGroup } from "@/lib/services" +import whiteboard from "@/images/whiteboard.jpg" import { clients, company } from "@/lib/site" export const metadata: Metadata = { @@ -47,11 +49,23 @@ const HomePage = () => (
The specialism Broadcast and streaming -

- Where we contract most, and the reason the reliability work below is not a claim. A - fault on a streaming platform is visible to millions of people at once, so it gets - found and fixed to a standard most systems never need. -

+
+

+ Where we contract most, and the reason the reliability work below is not a + claim. A fault on a streaming platform is visible to millions of people at once, + so it gets found and fixed to a standard most systems never need. +

+ {/* Deliberately out of focus. It is a real whiteboard from a real + engagement, and the client's architecture is theirs, not ours to + publish. See DESIGN.md, "Confidentiality". */} + A whiteboard covered in a hand drawn system architecture, deliberately out of focus +
diff --git a/packages/web/src/images/whiteboard.jpg b/packages/web/src/images/whiteboard.jpg new file mode 100644 index 0000000..4102a69 Binary files /dev/null and b/packages/web/src/images/whiteboard.jpg differ diff --git a/packages/web/test/pages.test.ts b/packages/web/test/pages.test.ts index a0df04c..9c554b1 100644 --- a/packages/web/test/pages.test.ts +++ b/packages/web/test/pages.test.ts @@ -207,3 +207,31 @@ describe("mobile layout", () => { expect(widths.size).toBeGreaterThan(2) }) }) + +describe("imagery", () => { + it("serves the image through the optimiser, in a modern format", async () => { + const { body } = await get("/") + const src = body.match(/src="(\/_next\/image[^"]*)"/)?.[1]?.replace(/&/g, "&") + expect(src, "no optimised image on the page").toBeDefined() + + const response = await fetch(`${baseUrl}${src}`, { + headers: { accept: "image/avif,image/webp,image/*" }, + }) + expect(response.status).toBe(200) + expect(response.headers.get("content-type")).toMatch(/avif|webp/) + }) + + it("gives the image dimensions, so nothing shifts as it loads", async () => { + const { body } = await get("/") + const tag = body.match(/]*_next\/image[^>]*>/)?.[0] ?? "" + expect(tag).toMatch(/width="\d+"/) + expect(tag).toMatch(/height="\d+"/) + }) + + it("describes the image for somebody who cannot see it", async () => { + const { body } = await get("/") + const tag = body.match(/]*_next\/image[^>]*>/)?.[0] ?? "" + const alt = tag.match(/alt="([^"]*)"/)?.[1] ?? "" + expect(alt.length).toBeGreaterThan(20) + }) +})