All lab entries

Lab note

LOG-001Notes

Opening the notebook

Why this site now has a lab notebook, what goes in it, and how an entry is put together.

3 min read
  • Next.js
  • MDX
  • Notes

The rest of this site is work I was paid to do. Case studies get written after the fact, once the result is known and the story has a shape — a weld tip measured to fifty microns, a processor that boots. They are tidy because the work was finished before the writing started.

This is the other pile. Things I build on my own time, where the interesting part is usually the middle: the measurement that disagreed with the datasheet, the approach that looked obvious and wasn't. Some of these finish. Some are dead ends I'd rather write down than repeat.

What goes in here

Roughly, anything that scratches an itch: signal processing on cheap radio hardware, computer vision experiments that never had a client, FPGA ideas that outlived the coursework, small tools I wrote because the existing ones annoyed me, and the occasional post-mortem on something I got wrong.

The bar is not "impressive". The bar is "I learned something and can show my work".

How an entry is put together

Each entry is two files of prose plus one registry record. The prose lives in content/labs/, one file per language:

content/labs/
  opening-the-notebook.en.mdx
  opening-the-notebook.tr.mdx

The record in lib/labs.ts is what the index, the sitemap and the language switcher actually read — title, summary, date, tags, and a loader for each body:

{
  id: "opening-the-notebook",
  date: "2026-07-31",
  minutes: 3,
  tags: ["Next.js", "MDX", "Notes"],
  locales: {
    en: { slug: "opening-the-notebook", title: "…", summary: "…" },
    tr: { slug: "defteri-acmak", title: "…", summary: "…" },
  },
  body: {
    en: () => import("@/content/labs/opening-the-notebook.en.mdx"),
    tr: () => import("@/content/labs/opening-the-notebook.tr.mdx"),
  },
}

Both languages are required by the type, so a half-translated entry cannot reach the site by accident. Adding draft: true keeps an entry out of every listing, route and sitemap until it's ready.

What an entry can use

Normal markdown, plus GitHub flavour — tables, task lists, strikethrough. On top of that, a handful of components are in scope without importing anything.

<Note> is the aside you just read. <Figure> is a captioned image with the dimensions next/image needs to reserve its space before loading:

<Figure
  src="/labs/waterfall.png"
  width={1600}
  height={900}
  alt="Waterfall plot of the 2.4 GHz band"
  caption="Forty seconds of the 2.4 GHz band, 2 MS/s"
/>

And <Stats> is for entries that produced numbers worth putting up front:

Files per entry
3
Languages
EN + TR
Build output
Static

How wide a thing is

The page is three columns wide. Prose sits in two of them, and that is a decision rather than a leftover: run a line of this size across the whole 1140px and it reaches about 150 characters, at which point the eye stops finding the start of the next one. Two columns is 46rem, which lands inside the 45–75 characters a line is comfortable at.

A picture has no such ceiling — a spectrogram is more readable the bigger it is — so every block takes a span of 1, 2 or 3 columns, and only the text defaults to 2:

<Figure src="/labs/wide-diagram.png" span={3} … />
<Note span={1} title="A short aside">…</Note>

Markdown itself has nowhere to put a prop, so a heading, a table or a paragraph that wants a different width gets wrapped in <Span>:

<Span cols={3}>
A table too wide to live inside the reading measure.
</Span>

And <Split> is the one thing normal flow cannot do — two blocks beside each other. The first child is the lead, everything after it becomes the column next to it, so a small figure no longer has to leave the width beside it empty:

<Split ratio="1-2">
  <Figure src="/labs/off-air.jpg" span={1} … />

  The paragraph that reads the picture.
</Split>

Below the width where two columns stop fitting, all of it collapses back to one and the lead simply sits above its text — the order it was written in.

Where this goes

I don't have a schedule and I'm not going to pretend otherwise. Entries land when something is worth writing down. The oldest habit from the lab bench is the one I'm trying to keep here: write it while you still remember why you tried it.