Skip to content
METYTOMETYTBook a Call

August 5, 2026 · 7 min read

Ember & Oak: A 42-Seat Steakhouse That Loads Like a Text File

Ember & Oak is not a client. It is a restaurant we invented — a forty-two-seat wood-fire steakhouse on King West — so we could build the site it would need and hand you the working thing instead of a description of it. The restaurant is fiction. Its own footer says so: A fiction, well done. The site is not fiction. Every line of it is real code, running now, and you can open it in a tab while you read this.

The brief we set ourselves

We wrote the brief a restaurant owner would write if they already knew what to ask for. One page. It has to feel like the room feels — dark, warm, unhurried. It has to take a reservation without sending the guest to somebody else's website. And it has to survive being inherited by nobody, because that is who maintains a restaurant site after the launch invoice is paid.

That last line set the shape of everything else. The site has zero runtime dependencies. No framework, no build step, no package to patch at midnight because of an advisory. The whole thing is a 278-line index.html, an 823-line stylesheet, and 306 lines of JavaScript. You can read the entire codebase in an afternoon. There is also nothing in it that can rot: no dependency tree to audit, no major version waiting to break, no toolchain that has to still work before anyone can edit a line. What ships is what a browser already knows how to read.

Why a restaurant site is really a booking problem

Strip away the photography and a restaurant site does one job: move a person from "where should we eat Friday" to "the table is held." Everything else on the page is either helping that happen or getting in its way.

Most restaurant sites hand that job to somebody else. A button on the homepage opens a reservation platform, the guest finishes the booking on a domain the restaurant does not own, and the restaurant pays for the introduction to a customer who was already on its website. Those platforms bill on a recurring basis with a per-cover fee on top, and the guest ends up belonging to the platform rather than to the room — which is why the reservation flow here is built to run on the restaurant's own domain.

So the flow lives on the page. Pick a date, pick a time, set the party size with a stepper that stops at one and at eight. Submit a date in the past and you get a specific error — not a red outline, a sentence — and focus moves back to the field that needs fixing. Submit a good one and the form is replaced by a confirmation panel that reads the booking back to you in words: the party, the day, the time. Every one of those state changes is announced through an aria-live region, so the flow reports itself to a screen reader the same way it reports itself to a pair of eyes.

The rest of the page answers the questions a booking raises. A real address block. An hours table with the closed night marked. Phone numbers as tel: links, so a thumb on a phone dials instead of copying digits. And a neighbourhood map built by hand as inline SVG — streets, labels, a pulsing marker — which means the "where are you" answer costs no third-party script, no API key, and no tracker following the guest home.

How it's built

The hero is the part people ask about. As you scroll, a fire burns — not a looping clip playing on its own clock, but a video scrubbed frame by frame against your scroll position. Scroll down and the coals build. Scroll up and they unbuild.

That effect fails badly if you build it the obvious way, because seeking around inside a normal video is slow: the decoder has to jump back to the last keyframe and replay forward to the frame you asked for. So the clip is encoded all-intra — 193 frames of H.264 where every single frame is a keyframe. Any scroll position decodes instantly, because there is nothing to replay.

It is also loaded through fetch into a blob rather than being pointed at directly. Static hosts that do not support HTTP Range requests hand back a video the browser will not seek inside; every seek pins to frame zero and the fire never moves. Fetching the file once and handing the browser a blob makes it seekable everywhere, on any host.

Around that sit the smaller pieces of texture: film grain generated on a canvas and rebuilt whenever the window resizes, so it never stretches; chapter sections whose backgrounds drift at a different rate than their copy; a custom cursor that thickens over anything clickable.

Typography is three self-hosted woff2 faces, 184 KB for the set, preloaded in the document head. Not one font request leaves the restaurant's domain.

Video is where restaurant sites usually go to die. The source media for this one ran to 201.9 MiB. Re-encoded, the set the site actually serves is 18.38 MiB — 18.6 MiB for the whole deployed site, markup and fonts included. room.mp4 alone came down from 42.1 MiB to 2.19 MiB, measured at a structural similarity of 0.988 against the original. That last number is the point: 0.988 means the difference is there in the file and not on the screen.

On 7 August 2026, Lighthouse 13.4.1 ran three times in sequence on mobile against the public site at emberandoak.metyto.com, not a preview deployment. The median of those three runs: 84 for performance, 96 for accessibility, 100 for best practices, 100 for SEO. First Contentful Paint 1.1 s, Largest Contentful Paint 4.0 s, 0 ms total blocking time, 0 cumulative layout shift. Accessibility stops at 96 for two reasons, both still open — four elements sit at a 3:1 contrast ratio, the footer text at #5f5b55 among them, and the brand link's accessible name does not match its visible label.

The constraints we refused to break

Four rules held for the whole build.

  • Nothing loads from a domain we do not control. Fonts are self-hosted. The map is drawn, not embedded. There is no analytics tag, no font CDN, no map iframe watching the guest.
  • No build step. The files that are edited are the files that ship. Nobody needs a working toolchain to change the hours.
  • The booking flow works without sight of the screen. Labelled fields, a real error message, and aria-live on the party count and the confirmation.
  • The fiction stays labelled. The restaurant does not exist, and the site says so in its own footer rather than letting a visitor find out later.

The last one is a business rule, not a technical one. A demo that quietly pretends to be a real restaurant is a demo you cannot trust about anything else.

What this means for your business

You do not need a wood-fire steakhouse to take three things from this.

Your booking, ordering, or quote flow belongs on your domain. Every time a customer finishes a transaction somewhere else, you rent access to a customer you already earned. Build the flow where you keep the relationship and the margin.

Weight is a cost you pay per visitor. A 201.9 MiB media set and an 18.4 MiB one look the same in a screenshot. On a phone on transit data, one of them arrives and one of them does not. Compression is not a technical nicety; it is whether the person who searched for you ever sees the page.

Maintenance cost is decided the day you choose the stack. A site with no dependencies has no upgrade path to fall off and no toolchain to reinstall before anyone can touch it. Changing your hours is an edit to one file. Ask what a change will cost you before you agree to how a site gets built, not after.

See it, then talk to us

The build is live at emberandoak.metyto.com. Scroll the hero slowly. Book a table for six. Try to submit yesterday's date. Open it on your phone and watch how fast the fire arrives.

Then, if you want the same standard pointed at a business that actually exists, book a free discovery call and tell us what your customers are trying to do on your site — and where they currently give up.