Skip to content

Repository files navigation

abacollc.com

Personal site for Charles Knight. Jekyll, no JavaScript, no third-party requests.

Content lives in Markdown and YAML; GitHub Actions builds it to static HTML on push. Nothing runs at request time.

Editing content

The site is three pages: the front page, /about/, and /abaco/. Almost everything you'd want to change is in _data/ or in one of those page files. You do not need to touch HTML or CSS to add a job, swap the cover photograph, or change a link.

To change Edit
The front page — cover photo, paragraph, the three links index.md
The long biography about.md
The organisations shown on About _data/roles.yml
The Charles Kerlee essay abaco.md
Which photo opens a page portrait: in that page's front matter
Email, location, LinkedIn, the nav _config.yml

The cover photograph

The front page opens with the abaco wordmark and one photograph. The photograph is set in index.mdcover, cover_w, cover_h, cover_alt, cover_credit — and nothing else on the site refers to it, so replacing it is a five-line edit plus dropping a file in assets/img/.

The one there now is a stand-in: a freely-licensed 1989 photograph of Hope Town harbour from Wikimedia Commons, chosen because it is the right island. It is CC BY-SA 2.0, which is why cover_credit names the photographer and links the licence — keep a credit of that shape for anything else pulled from Commons. When Charlie's own print is scanned, that obligation goes away with it; empty cover_credit and the caption disappears.

Set cover_w and cover_h to the file's real pixel dimensions. They reserve the space while the image loads, so the page doesn't jump. The image is shown at its own aspect ratio at every width — nothing is cropped in the browser — so crop it to the shape you want before saving it. The current one is 2400×1000.

The wordmark

_includes/abaco-mark.html is the wordmark inlined as SVG so it can take fill: currentColor and follow the --brand token into dark mode. assets/img/abaco-wordmark.svg is the same mark as a standalone file, and assets/img/abaco-wordmark@3x.png is the raster version the link-preview script uses. All three come from the identity pack; the "tag" lockup in that pack, which carries a strapline, is deliberately not used.

Writing and Ask, parked

/writing/ and /ask/ are switched off, at Charlie's request — the articles are on the Milgrom Daskam & Ellis site and he'd rather not republish them here for now. Nothing has been deleted. The six articles are in _drafts/, the two pages carry published: false, and the question bank is still in _data/ask.yml.

To bring them back:

git mv _drafts/*.md _posts/
# delete the `published: false` line from writing.md and ask.md
# add Writing and Ask back to `nav:` in _config.yml

The layouts, the CSS and the import script are all untouched, so that's the whole job. Restore the two together — several answers in _data/ask.yml link to /writing/ articles. Preview the drafts meanwhile with bundle exec jekyll serve --drafts.

Everything below, down to the end of this section, describes those parked pages and applies again once they're back.

Writing

Every article is kept in full on this site, including the six that first ran on the Milgrom Daskam & Ellis blog. That's deliberate: if those pages ever come down, nothing here breaks. Search engines are told this site is the canonical copy, and each imported piece still credits and links its original at the foot of the article.

One file per article in _posts/, named YYYY-MM-DD-slug.md, published at /writing/<slug>/:

---
title: "How to lose a deal in ten days"
date: 2026-08-14
excerpt: >-
  One or two sentences. Shown under the title in the article list.
venue: Colorado Real Estate Journal    # omit both of these
source_url: https://example.com/…      # for something written for this site
---

Body text in Markdown.

Leave venue and source_url off and it's simply an original post — no credit line, no outbound marker. That's the expected shape for anything written from here on.

To archive something published elsewhere, add it to ARTICLES in tools/import-article.py and run the script; it pulls the page, converts it to Markdown, and writes the post with front matter filled in. Header comments in that file explain the one-off dependencies. It overwrites generated posts, so don't hand-edit an imported article and then re-run it.

Add an interview question

In _data/ask.yml, under whichever theme fits:

- q: The question, written the way a host would actually ask it.
  id: corporate-transparency

id is required and must be unique across the file. It does two jobs: it's the deep link (/ask/#corporate-transparency), and it's the URL inside the pre-filled email. Reword a question freely, but don't change its id — that breaks any link already shared.

Add answer: and the question becomes expandable. Answers accept links:

- q: Has anyone actually read the Corporate Transparency Act?
  id: corporate-transparency
  answer: >-
    Short version, with the caveats: <a href="https://example.com">here</a>.

Themes are just list items — add, reorder, or delete them freely.

How the envelope buttons work

Every question carries an envelope that opens the visitor's mail client with the message already written — addressed to site.email, titled Interview question: <the question>, and with a body quoting the question and linking back to it. Someone who cares about one topic can start that exact conversation without composing anything.

It's all built in _layouts/ask.html; there's nothing to configure. One detail worth knowing if you edit that template: the question text is escaped with url_encode and then has + swapped back to %20. Jekyll's uri_escape is not safe here — it leaves & and # unescaped, so a question containing "M&A" would silently truncate the email body.

Photographs

Each page opens with one portrait, set in that page's own front matter:

portrait: /assets/headshots/milgrom-law.png
portrait_alt: Charles Knight in a grey and rust plaid jacket, against a concrete wall.
portrait_w: 600      # the file's real pixel width
portrait_h: 599      # and height — these reserve the space so the page doesn't jump

Photos are shown whole, at their natural proportions, never cropped to a fixed shape. On About the portrait floats inside the narrative and the text wraps around it; everywhere else it sits beside the page title. Below ~46rem everything stacks to a single column.

There are currently three photographs in assets/headshots/, so /ask/ shares the home page's. Drop a fourth file in and point ask.md at it to give every page its own.

Current assignments:

Page Photo
Home denver-housing-authroity.jpg
About milgrom-law.png
Writing hilltop-ventures.jpg
Ask denver-housing-authroity.jpg (shared with Home)
Abaco no portrait — the page opens straight into the prose

Add a photograph inside an article

Drop the file in assets/img/, then use one of two includes. Both need real pixel dimensions so the page doesn't jump while the image loads.

Inline, inside any Markdown page:

{% include figure.html src="/assets/img/pearl-street.jpg"
                       alt="Describe what's in the frame, for screen readers."
                       caption="Old South Pearl Street, September."
                       width="1600" height="1067" %}

Full-bleed band between sections — one per page at most:

{% include band.html src="/assets/img/denver.jpg" alt="…" caption="…"
                     width="2400" height="1200" %}

band does not currently go full-bleed inside an article. There is no breakout rule for it, so within .prose it renders at the 36rem measure — narrower than figure--wide — and its caption indents to a different edge than the image. It also crops (object-fit: cover), which nothing else on the site does. /abaco/ tried it and switched every image to figure--wide. Until someone adds the breakout CSS, reach for figure with wide="true".

Existing portraits are in assets/headshots/, named for where each one was used.

Link previews

assets/og-card.png is the 1200×630 image LinkedIn, Slack, and iMessage show when someone shares the site. It mirrors the front page — wordmark, then the cover photograph — and reads the same two image files the page does, so swapping the cover photo means regenerating the card:

python3 tools/make-og-card.py    # needs Pillow: pip3 install Pillow

The only text on it is the name and the location, in the NAME and PLACE constants at the top of the script. It carries no headline, because the page doesn't have one; the script warns on stderr if either line grows too wide for the card's margins.

The favicon is assets/favicon.svg (a CK monogram that inverts with the viewer's theme) and assets/apple-touch-icon.png — both still his initials rather than the firm's mark, which is the intended split: the site is his, the wordmark belongs to the LLC.

Preview locally

bundle install
bundle exec jekyll serve
# http://localhost:4000

Edits to Markdown, YAML, and CSS rebuild automatically. Changes to _config.yml need a restart.

Deploy

Push to main. .github/workflows/pages.yml builds with Jekyll 4 and publishes to GitHub Pages — live at https://abacollc.com in a minute or two. There is no staging; preview locally first.

Production is: GitHub Pages (hosting, free) + Cloudflare (DNS and domain registration, on Chris's personal account) + Google Workspace (his email — independent of the site). The full architecture, DNS zone, hard constraints (e.g. the repo must stay public or Pages stops serving), and a troubleshooting runbook live in CLAUDE.md.

How it's built

_config.yml          site metadata, nav, contact details
_data/               roles, ask — the content that isn't prose
_drafts/             the six articles, parked (see "Writing and Ask, parked")
_layouts/            home · about · writing · ask · page · post · default
_includes/           head · nav · footer · page-header · abaco-mark · figure
                     band · icon-mail · person-jsonld
tools/               make-og-card.py, import-article.py — not part of the build
index.md about.md abaco.md          the three live pages
writing.md ask.md                   parked, published: false
assets/css/site.css  the entire stylesheet
assets/fonts/        Fraunces, Source Serif 4, IBM Plex Sans Condensed (woff2, latin subset)
assets/headshots/    existing portraits
assets/img/abaco/    Charles Kerlee's photographs and book pages, for /abaco/
assets/img/          new photography goes here
assets/og-card.png   link-preview image, generated by tools/make-og-card.py

Design. The palette is sampled from the photographs — the cool studio backdrop becomes the page ground, the pocket square becomes the accent, the jacket becomes the secondary. So portraits sit inside the page instead of on top of it. The structural device is the question: sections open with one, and /ask/ is nothing but. All colours are CSS variables at the top of assets/css/site.css, with a dark-mode block right below.

Fonts are self-hosted, so the site makes zero third-party requests and works offline. Fraunces carries the display type (its WONK axis is what makes the italic in the headline distinctive); Source Serif 4 is the body; IBM Plex Sans Condensed handles labels and dates.

Structure borrows from Tailwind's Spotlight template — the two-column home page with a sidebar, the soft card panel that scales in on hover, the "Read article →" affordance, the rounded corners. The typography and palette are the site's own.

No JavaScript. The expandable answers on /ask/ are <details> elements, the envelope buttons are plain mailto: links, and the theme follows the operating system.

Verified: no horizontal overflow at 360–1440px on any page; WCAG AA contrast in both light and dark; animations disabled under prefers-reduced-motion; no third-party network requests; all 25 mail links decode to the correct subject, body, and anchor.

Still to do

  • Prose is a first draft. The home page short bio, the About narrative, and every question in _data/ask.yml were written from public sources (the Milgrom Daskam & Ellis profile and the Denver Housing Authority board page). Charlie should rewrite them in his own voice — particularly the questions, which are the point of the page.
  • Abaco, LLC now links from the footer to /abaco/, which explains where the name comes from. If Charlie holds a specific title at the LLC, that still wants adding to _data/roles.yml.
  • Photography. Beyond the headshots and /abaco/, there is nothing. The figure include is ready for whatever gets sourced. The band include is not — see below.

About

dads site

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages