Creative North Star: “The Engineering Notebook”
This is a record before it is a presentation. The system behaves like a well-kept lab notebook: everything is dated, everything is labeled, nothing is claimed that isn’t written down. Panels are pages — hairline-ruled rectangles that hold one coherent unit of content. Monospace runs in the margins as annotation: dates, section eyebrows, tags, the footer colophon. The sans face carries the substance. The separation is strict and it is the system’s core discipline.
The register is precise, quiet, and technical, and it is comfortable being dense. Information-forward is a feature here: a page may carry a lot at once, and scanability comes from consistent rhythm and hard hierarchy rather than from breathing room. Restraint is doing credibility work — an infrastructure engineer’s site earns trust by being exact, not by being impressive.
Two anti-references bound this from both sides. It is not a startup landing page: no gradient headline text, no floating testimonial cards, no funnel energy, no persuasion architecture. It is equally not an academic default: no serif CV page, no unstyled bullet lists, no 1990s faculty-homepage plainness. The system sits deliberately between them — contemporary and carefully built, but pointed at the record rather than at the reader’s decision.
Dark mode is a first-class state, not an inversion afterthought. It ships with its own hand-tuned text ramp because the utility-layer defaults were not good enough.
Key Characteristics:
-0.015em global, tighter on display)A slate-dominant neutral field with a single blue accent reserved for interaction, one cyan wash for taxonomy, and two colors that appear so rarely they function as punctuation.
ring-sky-400/85), plus the global outline: 2px solid rgba(14,165,233,0.85) with a 3px offset. Never decorative.cyan-700/15 wash. The one place taxonomy is allowed its own hue instead of borrowing slate.cyan-300/15 wash.::selection). It appears nowhere else in the system, which is exactly why it reads as a highlighter stroke rather than a brand color.blur-3xl and pointer-events-none. They are atmosphere, not palette. Nothing in the foreground may sample them.:root as --bg-primary.night-* scale.p.ring-slate-200 appears on 14 surfaces.assets/css/main.scss (e.g. .text-slate-600 → #b2c5d8) because Tailwind’s dark variants do not flip inside utility-heavy sections. Those overrides are load-bearing, not cruft.The Sky-Is-Interaction Rule. Sky means “this responds.” It is never a heading color, never a section-header decoration, never a fill for a static surface. If an element is not clickable or focused, it is not sky.
The Two-Authored-Themes Rule. Light and dark are both designed, and neither is derived from the other by filter or inversion. Any new color must be specified in both, and the dark value must be checked against the main.scss override block before being assumed.
Display Font: Space Grotesk (with ui-sans-serif, system-ui, sans-serif) Body Font: Space Grotesk — the same face, differentiated by weight and tracking rather than by family Label/Mono Font: IBM Plex Mono (with ui-monospace, SFMono-Regular, monospace)
Character: A two-face system doing three jobs. Space Grotesk’s slightly mechanical geometry keeps headings from reading as either corporate or scholarly — it is contemporary without being trendy. IBM Plex Mono is the annotation voice: every date, eyebrow, tag, and code span. The pairing is what makes the notebook metaphor legible; drop the mono and the system reads as a generic Tailwind site.
Both load from Google Fonts with preconnect, a preload hint, and a media="print" / onload swap, with a <noscript> fallback. Weights are deliberately narrow: 400/500/600/700 for the sans, 400/500/600 for the mono.
font-extrabold with -0.01em; archive cards use font-bold at 1.4rem.clamp(1rem, calc(0.97rem + 0.2vw), 1.08rem), line-height 1.7): The global default set on body.In-prose headings run 2.2rem / 1.9rem / 1.45rem at line-height 1.2 with mt-8 mb-3, well below the page-title scale so an article’s internal structure never competes with its title.
The Mono-Is-Metadata Rule. IBM Plex Mono carries dates, section eyebrows, tag chips, inline code, code blocks, and the footer colophon. It never sets a heading, never sets body copy, and never runs longer than a short phrase. If mono is carrying meaning rather than labeling it, it is being misused.
The Tight-Heading Rule. Every heading carries negative tracking — -0.015em globally on h1–h6, tightening toward -0.025em (tracking-tight) at title sizes and up. Headings never sit at default tracking.
A single centered column at max-w-7xl (80rem) with px-4 gutters stepping to px-6 at sm. Every page uses it; there is no full-bleed surface except the fixed ambient-orb layer and the sticky header’s background.
Vertical rhythm. Home sections run py-16, compressing to py-9 below sm, separated by a full-width hairline (border-t-2 on mobile, border-t from sm up — heavier on small screens where the section spacing is tighter). Content pages use py-10 stepping to py-12/py-16 at lg. Panel interiors step p-6 → p-8 @sm → p-10 @lg.
Grids. Two-column content pages put the sidebar on a fixed track: lg:grid-cols-[minmax(0,1fr)_300px] for post TOCs and [minmax(0,1fr)_320px] for project pages, both with lg:sticky lg:top-24 on the aside. The home hero inverts the usual weighting with lg:grid-cols-[minmax(0,0.76fr)_minmax(0,1.24fr)] — the photograph is deliberately the smaller half. Card grids vary by density: projects go sm:2 → xl:3, home project chips go sm:2 → lg:3 → xl:4, and the blog splits lg:[minmax(0,2fr)_minmax(280px,1fr)].
Density. Information-forward by intent. The home page stacks hero, projects, technologies, and blog with a sidebar; project pages carry two sidebar panels. The system does not use whitespace to signal importance — hierarchy comes from type scale and the hairline grid.
Breakpoints. Tailwind defaults, unmodified: sm 640px, md 768px, lg 1024px, xl 1280px. md is the navigation breakpoint (desktop nav and theme toggle appear; hamburger disappears). sm is the layout breakpoint for nearly everything else. Several components use max-sm: to increase weight on small screens rather than reduce it — borders thicken to 1.5px, shadows deepen, padding tightens.
Flat at rest; depth is a response. Surfaces sit flush in the field and are separated by a 1px ring, not by a shadow. The shadows that exist at rest are almost subliminal — a 1–3px offset at 6–8% opacity — present only to keep a white card from dissolving into a near-white field. Real depth is reserved for interaction: cards lift, buttons press, and the ring brightens.
Behind everything sits a fixed, non-interactive atmosphere layer: two large blurred orbs (cyan and fuchsia, blur-3xl, 10% light / 5% dark). This is the only ambient depth in the system and it never moves or responds.
The sticky header is the one element using material rather than geometry: bg-white/80 with backdrop-blur, so content dissolves under it rather than colliding with it.
box-shadow: 0 1px 2px rgba(15,23,42,0.06); dark 0 1px 2px rgba(2,6,23,0.28)): Post and archive cards. Barely visible by design.box-shadow: 0 1px 3px rgba(15,23,42,0.08)): Project cards. On mobile this deepens to 0 2px 6px rgba(15,23,42,0.1) where the ring alone reads too faintly.box-shadow: 0 4px 10px rgba(15,23,42,0.1); dark 0 5px 12px rgba(2,6,23,0.32)): The home hero photograph — the only element in the system permitted a genuine drop shadow.translateY(-4px) on project cards, -2px on the theme toggle, plus shadow-md): The primary depth signal.scale(0.99)): Every primary and secondary button.The Ring-First Rule. Structural separation is a 1px ring (ring-1 ring-slate-200, dark:ring-slate-600/75), never a shadow. If a new surface needs to be distinguished from the field, it gets a ring. Reach for a shadow only when the surface is also lifting.
The Flat-At-Rest Rule. A surface at rest carries at most a 3px, ≤8%-opacity shadow. Anything heavier must be justified by a state change — hover, focus, or the sticky header’s material.
Rectilinear and calm, with a radius scale that is genuinely functional rather than uniform. Corners get rounder as content gets softer: buttons and project cards are crisp at 0.375rem, panels and post cards sit at 0.5rem, and embedded media rounds further — prose images at 0.85rem, code blocks at 0.9rem (dropping to 0.5rem below sm, where a large radius on a narrow block wastes width).
Fully-round (9999px) is reserved for things that are conceptually tokens rather than containers: tag pills, technology badges, and the theme toggle. Archive tag chips are the deliberate exception — they use the smallest radius (0.25rem) with mono 10px uppercase text, reading as terminal output rather than as pills.
Borders are hairlines, almost always expressed as a ring or a low-opacity border (border-slate-900/15, border-slate-600/40). Solid full-opacity borders do not appear. Below sm, project cards thicken to 1.5px to survive the smaller viewport.
The home hero figure is the one framed object in the system: a bordered container with the image on a 16:10 crop (16:9 from sm) at saturate(0.92), capped with a bordered, centered mono caption bar — a plate in a notebook.
0.375rem), never pill-shaped.0.72rem 1.35rem padding, font-semibold at 0.94rem with leading-[1.1]. Inverts in dark mode to a light fill with dark text.border-slate-600/40) and ink text. Same geometry as primary.0.55rem 0.95rem padding at 0.86rem, min-h-[38px]. The only place the 44px floor is relaxed, and only for a secondary action adjacent to a primary one.0.35rem) only when focused.scale(0.99) on press; a 2px sky focus ring at 85% with a 2px offset, offset-coloured per theme.0.2rem 0.65rem at 0.78rem. Hover is a simple opacity: 0.8.0.25rem radius, mono 10px uppercase, slate wash. Capped at three per card.min-h-[44px]. Above six badges on mobile it collapses to a preview plus a <details> disclosure labeled with the full count.0.5rem for content panels and post cards; 0.375rem for project cards.white/90; project cards are fully transparent so the page field and orbs show through. Dark mode fills panels at slate-950/60–/70.ring-1 ring-slate-200 on panels; border-slate-900/15 on project cards.1.4rem for project cards (1.2rem below sm); 1.5rem → 2rem → 2.5rem for panels; 1rem → 1.25rem for archive cards.slate-500/50, and tint their background. Post cards brighten the ring to slate-400 and tint, without lifting.md and up): Text links at 0.98rem font-medium with 0.012em tracking, min-h-[44px], in a gap-8 row. Each carries a pseudo-element underline 1.5px tall, pre-scaled to 0.42 at zero opacity, expanding to full width at 55% opacity on hover and focus. The active link is font-semibold, near-black, with the underline at scale-x-1 and 95% opacity.md): A hamburger toggling a bordered panel of full-width 0.5rem-radius rows with a slate hover wash. The theme toggle joins the stack as the last row.aria-pressed and stays in sync across both instances. Hidden below md; lifts 2px on hover.The site has no forms. If one is added, it inherits the global transition and the global focus outline (2px solid rgba(14,165,233,0.85), 3px offset); match panel geometry — 0.5rem radius with a slate-200 hairline — rather than inventing a field style.
Major sections are introduced by a mono, uppercase, wide-tracked line prefixed with a double slash — // research infrastructure, // systems, // writing, // project. It sits directly above the heading in a muted slate, borrowing a code comment to label a region of the page. It appears on seven sections today and is the most recognizable move in the system.
This is a house pattern, not an invariant: use it where a section benefits from a label, and leave it off where it would be noise. Do not require one on every new section, and do not let its frequency creep to the point where it stops reading as an annotation.
ring-1 ring-slate-200, dark:ring-slate-600/75) before reaching for a shadow.190ms with cubic-bezier(0.22, 1, 0.36, 1), exposed as --motion-duration and --motion-ease. Card hovers may use 200ms ease-out and image scales 500ms; nothing else invents a timing.html.dark override block in assets/css/main.scss before assuming a dark: utility will win.focus-visible:ring-2 ring-sky-400/85 pair with a theme-correct ring-offset color.sm (max-sm:border-[1.5px], deeper card shadow) where hairlines stop reading.::selection at 28%; fuchsia is a 5–10% blurred orb. Neither is available to components.max-w-7xl container or introduce a full-bleed section. The only full-width layers are the ambient orbs and the sticky header’s material.night-* scale in tailwind.config.js. night-900 and night-800 are defined but used zero times, shadow-glow is likewise unused, and the single night-950 (#050a1a) usage is overridden by html.dark body { background: #050b17 !important }. The effective dark field is #050b17. Treat that config block as dead until it is either wired up or removed — do not build new work on those tokens.