{
    "type": "page",
    "title": "How this site is built",
    "canonical": "https://www.dealmobile.co.uk/colophon",
    "path": "/colophon",
    "url": "https://www.dealmobile.co.uk/colophon",
    "markdown": "https://www.dealmobile.co.uk/colophon.md",
    "json": "https://www.dealmobile.co.uk/colophon.json",
    "summary": "A theme written for this site, almost no third-party requests, and the solar year under the name.",
    "published": "2026-10-20T10:43:31+01:00",
    "modified": "2026-10-25T18:32:07+00:00",
    "image": {
        "url": "https://www.dealmobile.co.uk/sites/default/files/content/images/pages/colophon/hero.png",
        "alt": "A chain of five boxes: Markdown files in content, a CMS, a theme written for the site (highlighted), Cloudflare, and the visitor’s browser. Below it, a note that almost everything comes from this domain, the two exceptions being Cloudflare’s spam check and visit counter."
    },
    "fields": {
        "image_dark": null
    },
    "body": {
        "html": "<p>This site runs on Drupal 11 with a theme I wrote for it. There is no page builder, no front-end framework and no tracking. Everything a page needs comes from this domain, with two exceptions, both served by Cloudflare: the contact form’s spam check and the script that counts visits.</p>\n<h2 id=\"content\">Content</h2>\n<p>Every page, post, project and job is a content item with typed fields: a project has a kind, a status, a licence, the year it started, the technology it uses and its links. The CV is built from the job entries and a vocabulary of skills, so the page, the printed CV and the <a href=\"/cv.json\">JSON Resume</a> version always agree.</p>\n<p>The content started life as Markdown files with front matter. A small import command reads them and creates or updates each item by its path, so the site can be rebuilt from an empty database with one command, and running it twice changes nothing.</p>\n<p>This website was built, and all of its content written, by AI, so there may be inaccuracies. If you spot one, please tell me through the <a href=\"/contact\">contact form</a>.</p>\n<h2 id=\"live-figures-from-github\">Live figures from GitHub</h2>\n<p>The project pages show each repository’s latest release, last change and stars, and the home page lists the projects I’ve changed most recently. Cron fetches them from the GitHub API four times a day and keeps them in the database, so a page never waits on GitHub and your browser never talks to it. If GitHub is down, the last good figures stay.</p>\n<h2 id=\"type-and-colour\">Type and colour</h2>\n<p>Headings, dates, facts and controls are set in Schibsted Grotesk, drawn for a Scandinavian news publisher, and the reading text in Libre Caslon, a revival of the English printing face of almanacs and newspapers. Both are self-hosted under the SIL Open Font License, so there are no requests to a font service.</p>\n<p>The light theme is warm paper with near-black ink; the dark theme is near-black with cream ink. One vermilion accent marks the things to look at. The site follows your system’s setting unless you pick one in the footer, and remembers the choice in your browser.</p>\n<figure class=\"specimen\"><div class=\"specimen__faces\"><div class=\"specimen__face specimen__face--display\"><p class=\"specimen__sample\" aria-hidden=\"true\">Aa</p><p class=\"specimen__name\">Libre Caslon Display</p><p class=\"specimen__use\">The name and page titles</p></div><div class=\"specimen__face specimen__face--text\"><p class=\"specimen__sample\" aria-hidden=\"true\">Aa</p><p class=\"specimen__name\">Libre Caslon Text</p><p class=\"specimen__use\">Everything you read</p></div><div class=\"specimen__face specimen__face--ui\"><p class=\"specimen__sample\" aria-hidden=\"true\">Aa</p><p class=\"specimen__name\">Schibsted Grotesk</p><p class=\"specimen__use\">Dates, facts and controls</p></div></div><ul class=\"specimen__swatches\"><li class=\"specimen__swatch\"><span class=\"specimen__chip specimen__chip--page\" aria-hidden=\"true\"></span><span class=\"specimen__label\">Page</span> <code>--page</code></li><li class=\"specimen__swatch\"><span class=\"specimen__chip specimen__chip--ink\" aria-hidden=\"true\"></span><span class=\"specimen__label\">Ink</span> <code>--ink</code></li><li class=\"specimen__swatch\"><span class=\"specimen__chip specimen__chip--muted\" aria-hidden=\"true\"></span><span class=\"specimen__label\">Muted text</span> <code>--muted</code></li><li class=\"specimen__swatch\"><span class=\"specimen__chip specimen__chip--rule\" aria-hidden=\"true\"></span><span class=\"specimen__label\">Rules</span> <code>--rule</code></li><li class=\"specimen__swatch\"><span class=\"specimen__chip specimen__chip--link\" aria-hidden=\"true\"></span><span class=\"specimen__label\">Links</span> <code>--link</code></li><li class=\"specimen__swatch\"><span class=\"specimen__chip specimen__chip--sun\" aria-hidden=\"true\"></span><span class=\"specimen__label\">The sun</span> <code>--sun</code></li></ul><figcaption>The two faces, and the colours of the theme you’re reading in. Switch between light and dark in the footer to see the other.</figcaption></figure>\n<h2 id=\"security-and-privacy\">Security and privacy</h2>\n<p>The server sends a strict Content-Security-Policy that allows scripts, styles, fonts and images from this domain only. The one inline script, which sets the light or dark theme before the page draws, is allowed by its hash. The exceptions are Cloudflare’s: Turnstile, the contact form’s spam check, whose script and frame come from Cloudflare, and the Web Analytics script that counts visits. Pages are served over HTTPS with HSTS. The contact form is the only place that takes personal data. Turnstile tells people from bots, usually without asking you to do anything, and a hidden field catches simpler bots. Messages are emailed to me rather than kept on the site. The <a href=\"/privacy\">privacy notice</a> lists the short-lived anti-spam records the site does keep.</p>\n<h2 id=\"accessibility-and-testing\">Accessibility and testing</h2>\n<p>Every template is checked with axe against WCAG 2.2 AA in both themes, on a desktop and a phone. The layout works from a 320px screen up with no sideways scrolling, every control works from the keyboard, and the sun’s one movement, along the rule on your first page, is skipped if you’ve asked your system for reduced motion. The CV prints as a two-page A4 document.</p>"
    },
    "markdown_text": "---\ntitle: 'How this site is built'\ncanonical: 'https://www.dealmobile.co.uk/colophon'\nurl: 'https://www.dealmobile.co.uk/colophon'\ntype: Page\nsummary: 'A theme written for this site, almost no third-party requests, and the solar year under the name.'\n---\n\n# How this site is built\n\n![A chain of five boxes: Markdown files in content, a CMS, a theme written for the site (highlighted), Cloudflare, and the visitor’s browser. Below it, a note that almost everything comes from this domain, the two exceptions being Cloudflare’s spam check and visit counter.](https://www.dealmobile.co.uk/sites/default/files/styles/almanac_shot_md/public/content/images/pages/colophon/hero.png.webp?itok=W2cI-7rC)\n\nThis site runs on Drupal 11 with a theme I wrote for it. There is no page builder, no front-end framework and no tracking. Everything a page needs comes from this domain, with two exceptions, both served by Cloudflare: the contact form’s spam check and the script that counts visits.\n\n## Content\n\nEvery page, post, project and job is a content item with typed fields: a project has a kind, a status, a licence, the year it started, the technology it uses and its links. The CV is built from the job entries and a vocabulary of skills, so the page, the printed CV and the [JSON Resume](https://www.dealmobile.co.uk/cv.json) version always agree.\n\nThe content started life as Markdown files with front matter. A small import command reads them and creates or updates each item by its path, so the site can be rebuilt from an empty database with one command, and running it twice changes nothing.\n\nThis website was built, and all of its content written, by AI, so there may be inaccuracies. If you spot one, please tell me through the [contact form](https://www.dealmobile.co.uk/contact).\n\n## Live figures from GitHub\n\nThe project pages show each repository’s latest release, last change and stars, and the home page lists the projects I’ve changed most recently. Cron fetches them from the GitHub API four times a day and keeps them in the database, so a page never waits on GitHub and your browser never talks to it. If GitHub is down, the last good figures stay.\n\n## Type and colour\n\nHeadings, dates, facts and controls are set in Schibsted Grotesk, drawn for a Scandinavian news publisher, and the reading text in Libre Caslon, a revival of the English printing face of almanacs and newspapers. Both are self-hosted under the SIL Open Font License, so there are no requests to a font service.\n\nThe light theme is warm paper with near-black ink; the dark theme is near-black with cream ink. One vermilion accent marks the things to look at. The site follows your system’s setting unless you pick one in the footer, and remembers the choice in your browser.\n\nAa\n\nLibre Caslon Display\n\nThe name and page titles\n\n\n\nAa\n\nLibre Caslon Text\n\nEverything you read\n\n\n\nAa\n\nSchibsted Grotesk\n\nDates, facts and controls\n\n\n\n\n\n- Page `--page`\n- Ink `--ink`\n- Muted text `--muted`\n- Rules `--rule`\n- Links `--link`\n- The sun `--sun`\n\n*The two faces, and the colours of the theme you’re reading in. Switch between light and dark in the footer to see the other.*\n\n## Security and privacy\n\nThe server sends a strict Content-Security-Policy that allows scripts, styles, fonts and images from this domain only. The one inline script, which sets the light or dark theme before the page draws, is allowed by its hash. The exceptions are Cloudflare’s: Turnstile, the contact form’s spam check, whose script and frame come from Cloudflare, and the Web Analytics script that counts visits. Pages are served over HTTPS with HSTS. The contact form is the only place that takes personal data. Turnstile tells people from bots, usually without asking you to do anything, and a hidden field catches simpler bots. Messages are emailed to me rather than kept on the site. The [privacy notice](https://www.dealmobile.co.uk/privacy.md) lists the short-lived anti-spam records the site does keep.\n\n## Accessibility and testing\n\nEvery template is checked with axe against WCAG 2.2 AA in both themes, on a desktop and a phone. The layout works from a 320px screen up with no sideways scrolling, every control works from the keyboard, and the sun’s one movement, along the rule on your first page, is skipped if you’ve asked your system for reduced motion. The CV prints as a two-page A4 document.\n\n---\n\nIndex of this site: [llms.txt](https://www.dealmobile.co.uk/llms.txt)\n"
}