How This Set Was Drawn
Marrow is one of ten art directions built on the same Nomadic Owls content. The brief for this one: the agency's systems laid bare like architectural or engineering drawings — exposed grid lines, raw structure, nothing hidden. Not a terminal emulator, not a hacker aesthetic — a technical drawing. The reference points are structural drawing sets, surveyor's plats, and the kind of spec sheet an engineer signs off on: corner registration marks, running sheet numbers, scale notes, dimension lines, title blocks.
The whole page is modeled as a stack of numbered "sheets" (see the running SHEET 0X/08 label in every section header on the homepage). Each sheet gets
its own scale note, its own corner crop marks, and a border, exactly like a physical
drawing set would be paginated. The three pillars, six disciplines, and three client
projects are laid out as annotated tables and diagrams rather than the usual card grid,
because a spec sheet doesn't decorate — it labels.
Type & Palette
Display type is Archivo Black, used only in uppercase for structural
labels (sheet titles, pillar names, disciplines) and set at large sizes for the H1. Body
and every piece of "spec" copy — annotations, sheet meta, dimension labels, the
title blocks — runs in IBM Plex Mono, because mono is what
engineering documents and CAD annotations actually use. Both are self-hosted via @fontsource/archivo-black and @fontsource/ibm-plex-mono
(weights 400/500/600/700), imported directly in src/layouts/BaseLayout.astro — no CDN request, no FOIT/FOUT lottery.
The palette is deliberately narrow: #eeece6 paper, #111110 ink,
and a single #ff4d00 safety-orange accent. Orange only ever marks something
annotated — sheet numbers, dimension lines, discipline/pillar indices, hover states,
the "stamp" CTA. If it's orange, it's telling you something. Everything else stays
two-tone on purpose, which is what makes the accent legible as an accent instead of
decoration.
The Line-Draw Technique
Every dimension line, tick mark, and leader line on the page is a real inline SVG <line>/<path> with a shared CSS recipe:
.draw-line {
stroke-dasharray: 900;
stroke-dashoffset: 900;
transition: stroke-dashoffset 1.1s cubic-bezier(.16,1,.3,1);
}
.is-visible .draw-line { stroke-dashoffset: 0; }
A single vanilla-JS file (public/scripts/reveal.js, no framework, no bundler
step needed) runs one IntersectionObserver against every .sheet
section at a 0.18 threshold. When a sheet enters the viewport it gets .is-visible, which simultaneously drives the stroke animation and a plain
opacity/translateY fade on anything marked .sheet-fade. One observer, one
class toggle, no per-element JS wiring.
Every line also carries vector-effect="non-scaling-stroke" so the 1.5px
stroke stays crisp even where the SVG's viewBox is stretched to fill a
variable-width container. The corner registration marks are pure CSS instead (a circle
with two pseudo-element bars) since they're fixed-size decoration, not something that
needs to "draw on."
Card hover states (the six discipline tiles) use no JS at all — the tagline callout
is an opacity/translateY transition on :hover/:focus-within, so
keyboard users get the same callout on focus that mouse users get on hover. Its leader
line stays faintly visible at rest (a construction line waiting for its annotation) and
switches to full accent color on hover/focus. On touch screens, where :hover
never fires and a tap on a plain list item isn't guaranteed to move focus either, a (hover: none) media query shows every tagline permanently instead of hiding
content behind a gesture that may never happen.
prefers-reduced-motion: reduce is checked in both places: the JS short-circuits
to add .is-visible to every target immediately (skipping the observer
entirely), and a CSS media query force-sets every animated property to its resting state
as a belt-and-braces fallback.
Zero Generated Images
This direction uses no raster imagery at all. The paper grain visible across the whole
page is a single SVG feTurbulence filter, inlined as a data URI in body::after:
background-image: url("data:image/svg+xml,...
<filter id='n'>
<feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/>
<feColorMatrix type='saturate' values='0'/>
</filter>...");
opacity: .05; mix-blend-mode: multiply;
Tiled at 140×140px with multiply blending and 5% opacity, it reads as
the same fine, neutral concrete-paper grain the brief describes, at zero network weight
and perfect sharpness on every screen density. The graph-paper grid underneath the whole
page is the same idea: two repeating-linear-gradients on body,
no image. Given the brief's 0–1 image budget and the "expose the structure" concept,
a photographed concrete texture felt like exactly the kind of surface decoration this
direction is arguing against — so the budget went unused by choice, not oversight.
Two Honest Tradeoffs
- Fixed dash length instead of measured paths. The 900-unit
stroke-dasharrayis a constant, not computed fromgetTotalLength(). It works here because every animated line in this design is a short straight segment or two-point polyline well under that length, and it avoids a layout-thrashing JS pass on every path at load. It would break silently (the line would appear to "jump" instead of draw) if a future section needed a long or curved path — that would need the measured version. - Density over breathing room. A spec-sheet layout wants dividers, labels, and tight columns; most "premium" web design wants generous whitespace. This build leans into the former — borders between every pillar/discipline/work row, dense mono annotations — which is authentic to the concept but does cost some scannability on first glance, especially on mobile where columns collapse to one and the page runs longer than a typical marketing scroll. Sheet numbers and scale notes are there partly to compensate: they give the eye a fixed anchor per section even when the content inside is dense.